Chatinator.Bot.Hosting
0.3.833
dotnet add package Chatinator.Bot.Hosting --version 0.3.833
NuGet\Install-Package Chatinator.Bot.Hosting -Version 0.3.833
<PackageReference Include="Chatinator.Bot.Hosting" Version="0.3.833" />
<PackageVersion Include="Chatinator.Bot.Hosting" Version="0.3.833" />
<PackageReference Include="Chatinator.Bot.Hosting" />
paket add Chatinator.Bot.Hosting --version 0.3.833
#r "nuget: Chatinator.Bot.Hosting, 0.3.833"
#:package Chatinator.Bot.Hosting@0.3.833
#addin nuget:?package=Chatinator.Bot.Hosting&version=0.3.833
#tool nuget:?package=Chatinator.Bot.Hosting&version=0.3.833
Chatinator Bot SDK for .NET
A .NET SDK for building bots on the Chatinator platform. Provides a SignalR-based gateway client for real-time events and a Refit-based REST client for the HTTP API, with a command framework for handling slash commands, context menus, and component interactions.
Project Structure
| Project | Description |
|---|---|
Chatinator.Bot |
Top-level client (ChatinatorBotClient) combining REST and gateway, plus DI extensions |
Chatinator.Bot.Core |
Shared models, events, intents, and permissions used across all projects |
Chatinator.Bot.Gateway |
SignalR gateway client with session resume, entity cache, and backpressure |
Chatinator.Bot.Rest |
Refit-based HTTP client with rate limiting, resilience (retry + circuit breaker), and auth |
Chatinator.Bot.Builders |
Fluent builders for slash commands, embeds, components, polls, messages, and modals |
Chatinator.Bot.Interactions |
Command framework: attribute-based slash commands, context menus, component/modal handlers |
Chatinator.Bot.Hosting |
IHostedService lifecycle, health checks, and Prometheus-compatible metrics |
Chatinator.Bot.Tests |
Unit tests for all of the above |
Getting Started
Install
Reference the hosting package (which pulls in all dependencies):
<ItemGroup>
<ProjectReference Include="path/to/Chatinator.Bot.Hosting/Chatinator.Bot.Hosting.csproj" />
</ItemGroup>
Configure and Connect
using Chatinator.Bot;
using Chatinator.Bot.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddChatinatorBot(options =>
{
options.Token = builder.Configuration["Bot:Token"]!;
options.BaseUrl = builder.Configuration["Bot:BaseUrl"]!;
});
builder.Services.AddChatinatorBotHosted();
var app = builder.Build();
await app.RunAsync();
The hosted service connects on startup and disconnects gracefully on shutdown.
Basic Bot Example
Subscribe to gateway events directly on the ChatinatorBotClient:
builder.Services.AddChatinatorBot(options =>
{
options.Token = "your-bot-token";
options.BaseUrl = "https://app.chatinator.net";
options.Intents = GatewayIntent.GuildMessages | GatewayIntent.MessageContent;
});
builder.Services.AddChatinatorBotHosted();
var app = builder.Build();
var bot = app.Services.GetRequiredService<ChatinatorBotClient>();
bot.Ready += () =>
{
Console.WriteLine("Bot is ready!");
return Task.CompletedTask;
};
bot.MessageReceived += async msg =>
{
// Echo messages back via the REST API
await bot.Rest.Messages.SendMessageAsync(
msg.Message.ChannelId,
new SendMessageRequest { Content = $"Echo: received a message" });
};
await app.RunAsync();
Slash Commands
Defining Commands
Create a class that inherits InteractionModule and decorate methods with [SlashCommand]:
using Chatinator.Bot.Interactions.Attributes;
using Chatinator.Bot.Interactions.Modules;
public class PingModule : InteractionModule
{
[SlashCommand("ping", "Check if the bot is alive")]
public async Task PingAsync()
{
await RespondAsync("Pong!");
}
[SlashCommand("echo", "Repeat your message back")]
public async Task EchoAsync(
[Option("text", "The text to echo")] string text)
{
await RespondAsync(text);
}
}
Registering Commands
builder.Services.AddChatinatorBot(options => { /* ... */ });
builder.Services.AddInteractions(interactions =>
{
interactions.AddModule<PingModule>();
});
builder.Services.AddChatinatorBotHosted();
Or scan an entire assembly:
builder.Services.AddInteractions(interactions =>
{
interactions.AddModulesFromAssembly(typeof(PingModule).Assembly);
});
Command Groups
Nest commands under a parent using [Group]:
[Group("settings", "Bot configuration commands")]
public class SettingsModule : InteractionModule
{
[SlashCommand("get", "Get a setting value")]
public async Task GetAsync([Option("key", "The setting key")] string key)
{
await RespondAsync($"Value for {key}: ...");
}
}
This registers as /settings get <key>.
Context Menu Commands
public class ContextMenuModule : InteractionModule
{
[UserCommand("Get User Info")]
public async Task UserInfoAsync()
{
await RespondAsync($"User: {Context.UserId}");
}
[MessageCommand("Quote Message")]
public async Task QuoteAsync()
{
await RespondAsync("Quoted!");
}
}
Preconditions
Restrict commands with built-in or custom preconditions:
[RequireGuild]
[SlashCommand("server-only", "Only works in guilds")]
public async Task ServerOnlyAsync()
{
await RespondAsync("You're in a guild!");
}
[RequirePermission(GuildPermission.ManageMessages)]
[SlashCommand("purge", "Delete messages")]
public async Task PurgeAsync() { /* ... */ }
[RequireBotOwner]
[SlashCommand("shutdown", "Shut down the bot")]
public async Task ShutdownAsync() { /* ... */ }
Cooldowns
[Cooldown(seconds: 10, scope: CooldownScope.User)]
[SlashCommand("daily", "Claim your daily reward")]
public async Task DailyAsync() { /* ... */ }
Component Interactions
Sending Buttons
var components = new ComponentBuilder()
.WithButton("Confirm", "confirm-123", style: 3) // success
.WithButton("Cancel", "cancel-123", style: 4) // danger
.Build();
Handling Button Clicks
Use [ComponentInteraction] with wildcard patterns:
[ComponentInteraction("confirm-*")]
public async Task HandleConfirmAsync()
{
await RespondAsync("Confirmed!", ephemeral: true);
}
The * suffix matches any custom ID starting with confirm-.
Modal Interactions
[ModalInteraction("feedback-modal")]
public async Task HandleFeedbackAsync()
{
await RespondAsync("Thanks for your feedback!");
}
Gateway Events
All events are exposed as Func<TEventArgs, Task> delegates on ChatinatorBotClient:
Lifecycle: Ready, Disconnected
Messages: MessageReceived, MessageDeleted, MessageEdited
Reactions: ReactionAdded, ReactionRemoved
Moderation: MemberKicked, MemberBanned, MemberUnbanned, MemberTimedOut, MemberTimeoutRemoved, NicknameChanged
Voice: VoiceStateUpdated
Presence: PresenceUpdated (requires privileged GuildPresences intent)
Emotes: EmoteCreated, EmoteUpdated, EmoteDeleted
Sounds: SoundCreated, SoundUpdated, SoundDeleted
Scheduled Events: ScheduledEventCreated, ScheduledEventUpdated, ScheduledEventCancelled, ScheduledEventInterestUpdated
Threads: ThreadCreated, ThreadMessageReceived, ThreadArchived, ThreadDeleted
Pins: MessagePinned, MessageUnpinned
Typing: UserStartedTyping, UserStoppedTyping
Polls: PollVoteUpdated, PollClosed
Interactions: InteractionReceived
Auto-Moderation: AutoModActionExecuted
REST API
The REST client is accessible via bot.Rest and exposes typed Refit interfaces:
| Client | Operations |
|---|---|
Rest.Guilds |
Get guild, update settings |
Rest.Channels |
Create, edit, delete, reorder channels |
Rest.Messages |
Send, edit, delete, bulk delete messages |
Rest.Members |
List, kick, ban, unban, timeout members |
Rest.Roles |
Create, edit, delete, reorder roles |
Rest.Threads |
Create, archive, delete threads |
Rest.Reactions |
Add, remove, list reactions |
Rest.ScheduledEvents |
Create, update, cancel events |
Rest.Stickers |
List, get stickers |
Rest.AutoMod |
Create, update, delete auto-mod rules |
Rest.AuditLog |
Query guild audit log entries |
Rest.Voice |
Get voice channel join tokens |
Rest.Webhooks |
Create, edit, delete, execute webhooks |
Rest.Interactions |
Respond to an interaction (callback) |
Rest.Commands |
Register, list, delete application commands |
Builders
Slash Command Builder
var command = new SlashCommandBuilder()
.WithName("greet")
.WithDescription("Greet a user")
.AddOption("user", type: 6, "The user to greet", required: true)
.AddOption("message", type: 3, "Custom greeting")
.Build();
Embed Builder
var embed = new EmbedBuilder()
.WithTitle("Server Stats")
.WithDescription("Current statistics for the server")
.WithColor(0x5865F2)
.WithTimestamp(DateTimeOffset.UtcNow)
.AddField("Members", "142", inline: true)
.AddField("Channels", "12", inline: true)
.WithFooter("Updated every 5 minutes")
.WithThumbnail("https://example.com/icon.png")
.Build();
Component Builder
var components = new ComponentBuilder()
.WithButton("Accept", "accept-btn", style: 3, emoji: "\u2705")
.WithButton("Deny", "deny-btn", style: 4, emoji: "\u274C")
.NewRow()
.WithLinkButton("Documentation", "https://docs.chatinator.net")
.Build();
Poll Builder
var poll = new PollBuilder()
.WithQuestion("What should we play tonight?")
.AddAnswer("Valorant")
.AddAnswer("Minecraft")
.AddAnswer("Among Us")
.WithDuration(24)
.WithMultiselect()
.Build();
Message Builder
Compose rich messages with content, embeds, components, and attachments:
var message = new MessageBuilder()
.WithContent("Here are the results:")
.AddEmbed(e => e
.WithTitle("Poll Results")
.WithDescription("The community has spoken!")
.WithColor(0x57F287))
.Build();
Context Menu Command Builder
var userCommand = new ContextMenuCommandBuilder()
.WithName("Report User")
.AsUserCommand()
.Build();
var messageCommand = new ContextMenuCommandBuilder()
.WithName("Translate Message")
.AsMessageCommand()
.Build();
Modal Builder
var modal = new ModalBuilder()
.WithCustomId("feedback-modal")
.WithTitle("Submit Feedback")
.AddTextInput("feedback", "Your feedback", required: true, placeholder: "Tell us what you think...")
.Build();
Hosting
Hosted Service
AddChatinatorBotHosted() registers an IHostedService that calls ConnectAsync on start and DisconnectAsync on stop:
builder.Services.AddChatinatorBot(options => { /* ... */ });
builder.Services.AddChatinatorBotHosted();
When an interaction service is registered (AddInteractions), the hosted service also:
- Bridges interactions — inbound gateway interactions are dispatched to your command modules, and each handler's reply is sent back via the interaction-callback REST endpoint.
- Self-registers commands — on
Ready, the bot's slash and context-menu commands are synced to the platform (created if missing), so they appear to users without a manual step.
Both happen automatically; no extra wiring is needed beyond AddInteractions + AddChatinatorBotHosted.
Health Checks
Adds a health check that reports gateway state (Healthy/Degraded/Unhealthy):
builder.Services.AddHealthChecks()
.AddChatinatorBotCheck();
Metrics
Registers Prometheus-compatible counters and histograms via System.Diagnostics.Metrics:
builder.Services.AddChatinatorBotMetrics();
Available metrics:
chatinator.bot.commands.dispatched-- total commands dispatchedchatinator.bot.interactions.failed-- total interaction handler errorschatinator.bot.gateway.events.received-- total gateway events receivedchatinator.bot.gateway.reconnections-- total reconnectionschatinator.bot.rest.requests-- total REST API requestschatinator.bot.rest.rate_limits-- total rate limit hitschatinator.bot.commands.duration-- command execution duration (ms)
Configuration
ChatinatorBotOptions
| Property | Default | Description |
|---|---|---|
Token |
(required) | Bot authentication token |
BaseUrl |
(required) | Chatinator API base URL (e.g. https://app.chatinator.net) |
GatewayUrl |
{BaseUrl}/hubs/bot |
Override the gateway hub URL |
Intents |
AllUnprivileged |
Gateway intents controlling which events are received |
AutoReconnect |
true |
Automatically reconnect on connection loss |
Gateway Intents
Control which events the bot receives. Combine with bitwise OR:
options.Intents = GatewayIntent.GuildMessages
| GatewayIntent.GuildMessageReactions
| GatewayIntent.MessageContent; // privileged
Unprivileged intents: GuildMessages, GuildMessageReactions, GuildMembers, GuildVoiceStates, DirectMessages, GuildEmotes, GuildSounds, GuildScheduledEvents, GuildModeration, Typing, Polls, Threads, Pins
Privileged intents (must be enabled in the application settings): GuildPresences, MessageContent
Convenience values: AllUnprivileged, All
Gateway Options (advanced)
| Property | Default | Description |
|---|---|---|
EventQueueCapacity |
1000 | Bounded channel capacity before backpressure is applied |
REST Client Options
| Property | Default | Description |
|---|---|---|
EnableResilience |
true |
Enable retry with exponential backoff and circuit breaker |
Session Resume
When the gateway connection is lost and auto-reconnect is enabled, the SDK automatically attempts to resume the previous session:
- The SignalR
WithAutomaticReconnect()policy re-establishes the transport connection. - On reconnection, the SDK sends a
Resumerequest with the session ID and last sequence number. - If the server accepts the resume, missed events are replayed and the
SessionResumedevent fires. - If the session is invalid (e.g. too much time elapsed), the server responds with
InvalidSessionand the SDK automatically re-identifies with a fresh session.
The gateway tracks state through these transitions: Disconnected → Connecting → Identifying → Connected → Reconnecting → Resuming → Connected.
Examples
Chatinator.Bot.Examples/PingBot— a minimal bot.examples/DemoBot(repo root) — a full tour of the SDK: slash and context-menu commands, command self-registration, embeds, ephemeral replies, preconditions, cooldowns, broad gateway-event logging, presence, and the REST API. Its README also documents the features that do not yet round-trip end-to-end (interactive components, modals, autocomplete).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Chatinator.Bot (>= 0.3.833)
- Microsoft.AspNetCore.SignalR.Client (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.10)
- Refit (>= 13.1.0)
- Refit.HttpClientFactory (>= 13.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.833 | 45 | 9/10/2026 |
| 0.3.832 | 45 | 9/10/2026 |
| 0.3.831 | 42 | 9/10/2026 |
| 0.3.830 | 48 | 9/10/2026 |
| 0.3.829 | 47 | 9/10/2026 |
| 0.3.828 | 66 | 9/10/2026 |
| 0.3.826 | 71 | 9/10/2026 |
| 0.3.825 | 92 | 9/1/2026 |
| 0.3.824 | 90 | 8/30/2026 |
| 0.3.809 | 158 | 8/2/2026 |
| 0.3.807 | 115 | 8/2/2026 |
| 0.3.806 | 108 | 8/2/2026 |
| 0.3.804 | 105 | 7/30/2026 |
| 0.3.803 | 97 | 7/30/2026 |
| 0.3.801 | 104 | 7/27/2026 |
| 0.3.800 | 108 | 7/27/2026 |
| 0.3.799 | 103 | 7/26/2026 |
| 0.3.798 | 110 | 7/18/2026 |
| 0.3.784 | 107 | 7/17/2026 |
| 0.3.783 | 97 | 7/17/2026 |