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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chatinator.Bot.Hosting" Version="0.3.833" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Chatinator.Bot.Hosting" Version="0.3.833" />
                    
Directory.Packages.props
<PackageReference Include="Chatinator.Bot.Hosting" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Chatinator.Bot.Hosting --version 0.3.833
                    
#r "nuget: Chatinator.Bot.Hosting, 0.3.833"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Chatinator.Bot.Hosting@0.3.833
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Chatinator.Bot.Hosting&version=0.3.833
                    
Install as a Cake Addin
#tool nuget:?package=Chatinator.Bot.Hosting&version=0.3.833
                    
Install as a Cake Tool

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-.

[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();
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 dispatched
  • chatinator.bot.interactions.failed -- total interaction handler errors
  • chatinator.bot.gateway.events.received -- total gateway events received
  • chatinator.bot.gateway.reconnections -- total reconnections
  • chatinator.bot.rest.requests -- total REST API requests
  • chatinator.bot.rest.rate_limits -- total rate limit hits
  • chatinator.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:

  1. The SignalR WithAutomaticReconnect() policy re-establishes the transport connection.
  2. On reconnection, the SDK sends a Resume request with the session ID and last sequence number.
  3. If the server accepts the resume, missed events are replayed and the SessionResumed event fires.
  4. If the session is invalid (e.g. too much time elapsed), the server responds with InvalidSession and the SDK automatically re-identifies with a fresh session.

The gateway tracks state through these transitions: DisconnectedConnectingIdentifyingConnectedReconnectingResumingConnected.

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed