gaato/discord/bot does not have a README file

EventMiddleware

type EventMiddleware = async (GatewayCtx,
Event
, async (
Event
) -> Unit) -> Unit

Runs once per decoded gateway event, around the handler fan-out. next(event) spawns the typed and raw handlers for (a possibly transformed) event and returns once they are spawned, not completed. Not calling next drops the event for handlers only: cache updates, decode-error observation, collectors, and interaction routing are wire-level machinery that runs before this chain.

BotError

pub(all) suberror BotError {
FatallyClosed(code~ : Int)
InvalidShardConfig(message~ : String)
SessionStartLimitExceeded(required~ : Int, remaining~ : Int, reset_after_ms~ : Int64)
} derive(
Debug
)

Fatal runtime failures reported by Discord.
impl Show for BotError

Bot

pub struct Bot {
// private fields
}

Native gateway executor for a gateway-free application core.

Bot::Bot

fn Bot::Bot(app :
App
, token~ : String, intents? :
Intents
, client? :
Client
, gateway_url? : String, shards? : ShardConfig, compress? : Bool, identify_queue? : &
IdentifyQueue
) -> Bot

Create a gateway runner for app. When intents is omitted, the bot infers the union of intents required by its typed event subscriptions at run time (privileged intents are only inferred, never invented — they must still be enabled in the developer portal). client supplies a preconfigured REST client; by default one is built from token. shards, compress, and identify_queue configure sharding, transport compression, and cross-process identify coordination.

Bot::attach_cache

fn Bot::attach_cache(self : Bot, cache :
InMemoryCache
) -> Unit

Feeds every decoded gateway event into an opt-in cache before dispatching typed and raw event handlers.

Bot::middleware

fn Bot::middleware(self : Bot, middleware : async (GatewayCtx,
Event
, async (
Event
) -> Unit) -> Unit) -> Unit

Install gateway event middleware. The first installed middleware is outermost. The chain runs serially in the shard dispatch loop, so middleware must return promptly. A dropped event emits no EventDispatched telemetry. Middleware cannot widen intents or the gateway event filter.

Bot::on

fn[T] Bot::on(self : Bot, event : EventType[T], handler : async (GatewayCtx, T) -> Unit) -> Unit

Subscribe a typed handler to one gateway event (see Events for the descriptors). The event's required intents join the inferred intent set when Bot(...) omits explicit intents. Handlers run through the event middleware chain; a raised error is reported via the app's failure policy without stopping the bot.

Bot::on_decode_error

fn Bot::on_decode_error(self : Bot, handler : (String, Json) -> Unit) -> Unit

Observe gateway events whose known payload failed typed decoding.

marker is the full synthetic event type DECODE_ERROR:<event-name>:<decode-error>, and payload is Discord's raw event data. Handlers run synchronously in the dispatch loop and should return promptly. Registering a handler does not add gateway intents or widen the event filter.

Bot::on_event

fn Bot::on_event(self : Bot, handler : async (GatewayCtx,
Event
) -> Unit) -> Unit

Subscribe to the raw event stream: every decoded gateway dispatch, including Resumed and Unknown, without payload projection. Unlike Bot::on, this adds nothing to the inferred intent set.

Bot::on_telemetry

fn Bot::on_telemetry(self : Bot, hook : (
TelemetryEvent
) -> Unit raise) -> Unit

Observe structured gateway, dispatch, and REST telemetry aggregated by this bot. Hooks run synchronously and should return promptly.

Bot::run

async fn Bot::run(self : Bot) -> Unit

Connect and process gateway events until graceful shutdown or a fatal close.

Bot::service

fn Bot::service(self : Bot, name~ : String, handler : async (GatewayCtx) -> Unit) -> Unit

Register a long-running background task started alongside the shards when the bot runs (e.g. a periodic status updater). name labels the service in failure reports. A raised error is reported via the app's failure policy and stops only that service, not the bot.

EventType

pub struct EventType[T] {
// private fields
}

A typed projection from the general gateway event enum.

EventType::kind

The untyped event kind used by gateway filtering and intent calculation.

EventType::project

fn[T] EventType::project(self : EventType[T], event :
Event
) -> T?

Extract the typed payload when event is this descriptor's variant.

EventType::required_intents

fn[T] EventType::required_intents(self : EventType[T]) ->
Intents

Gateway intents that can deliver this event.

Events

pub struct Events {
}

Namespace for typed gateway event descriptors.

The payload-free Resumed event and Unknown are available only through the low-level event stream.

Events::application_command_permissions_update

Typed descriptor for APPLICATION_COMMAND_PERMISSIONS_UPDATE — the permission overwrites of an application command were updated. Not gated by a gateway intent.

Events::auto_moderation_action_execution

Typed descriptor for AUTO_MODERATION_ACTION_EXECUTION — an auto moderation rule triggered and its action was executed. Delivered under the AUTO_MODERATION_EXECUTION intent.

Events::auto_moderation_rule_create

Typed descriptor for AUTO_MODERATION_RULE_CREATE — an auto moderation rule was created. Delivered under the AUTO_MODERATION_CONFIGURATION intent.

Events::auto_moderation_rule_delete

Typed descriptor for AUTO_MODERATION_RULE_DELETE — an auto moderation rule was deleted. Delivered under the AUTO_MODERATION_CONFIGURATION intent.

Events::auto_moderation_rule_update

Typed descriptor for AUTO_MODERATION_RULE_UPDATE — an auto moderation rule was updated. Delivered under the AUTO_MODERATION_CONFIGURATION intent.

Events::channel_create

Typed descriptor for CHANNEL_CREATE — a guild channel was created. Delivered under the GUILDS intent.

Events::channel_delete

Typed descriptor for CHANNEL_DELETE — a guild channel was deleted. Delivered under the GUILDS intent.

Events::channel_info

Typed descriptor for CHANNEL_INFO — ephemeral voice-channel status and session data for a guild's channels. Not gated by a gateway intent.

Events::channel_pins_update

Typed descriptor for CHANNEL_PINS_UPDATE — a message was pinned or unpinned (not fired when a pinned message is deleted). Delivered under the GUILDS or DIRECT_MESSAGES intent.

Events::channel_update

Typed descriptor for CHANNEL_UPDATE — a guild channel was updated. Delivered under the GUILDS intent.

Events::entitlement_create

Typed descriptor for ENTITLEMENT_CREATE — an entitlement was created, e.g. a user purchased or was granted a premium offering. Not gated by a gateway intent.

Events::entitlement_delete

Typed descriptor for ENTITLEMENT_DELETE — an entitlement was deleted, e.g. Discord refunded or revoked it (not fired on normal expiry). Not gated by a gateway intent.

Events::entitlement_update

Typed descriptor for ENTITLEMENT_UPDATE — an entitlement was renewed or ended. Not gated by a gateway intent.

Events::guild_audit_log_entry_create

Typed descriptor for GUILD_AUDIT_LOG_ENTRY_CREATE — an audit log entry was created. Delivered under the GUILD_MODERATION intent; the bot also needs the View Audit Log permission.

Events::guild_ban_add

Typed descriptor for GUILD_BAN_ADD — a user was banned from a guild. Delivered under the GUILD_MODERATION intent.

Events::guild_ban_remove

Typed descriptor for GUILD_BAN_REMOVE — a user was unbanned from a guild. Delivered under the GUILD_MODERATION intent.

Events::guild_create

Typed descriptor for GUILD_CREATE — the initial lazy-load of each guild after READY, a guild becoming available again, or the bot joining a new guild. Delivered under the GUILDS intent.

Events::guild_delete

Typed descriptor for GUILD_DELETE — the bot was removed from a guild, or the guild became unavailable during an outage (check the unavailable field to tell the two apart). Delivered under the GUILDS intent.

Events::guild_emojis_update

Typed descriptor for GUILD_EMOJIS_UPDATE — a guild's custom emoji set changed. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_integrations_update

Typed descriptor for GUILD_INTEGRATIONS_UPDATE — a guild integration was created, updated, or deleted. Delivered under the GUILD_INTEGRATIONS intent.

Events::guild_member_add

Typed descriptor for GUILD_MEMBER_ADD — a user joined a guild. Delivered under the privileged GUILD_MEMBERS intent.

Events::guild_member_remove

Typed descriptor for GUILD_MEMBER_REMOVE — a user left a guild, or was kicked or banned. Delivered under the privileged GUILD_MEMBERS intent.

Events::guild_member_update

Typed descriptor for GUILD_MEMBER_UPDATE — a guild member was updated (roles, nick, timeout, ...). Delivered under the privileged GUILD_MEMBERS intent.

Events::guild_members_chunk

Typed descriptor for GUILD_MEMBERS_CHUNK — one page of the response to a Request Guild Members gateway command. Not gated by a gateway intent.

Events::guild_role_create

Typed descriptor for GUILD_ROLE_CREATE — a role was created. Delivered under the GUILDS intent.

Events::guild_role_delete

Typed descriptor for GUILD_ROLE_DELETE — a role was deleted. Delivered under the GUILDS intent.

Events::guild_role_update

Typed descriptor for GUILD_ROLE_UPDATE — a role was updated. Delivered under the GUILDS intent.

Events::guild_scheduled_event_create

Typed descriptor for GUILD_SCHEDULED_EVENT_CREATE — a scheduled event was created. Delivered under the GUILD_SCHEDULED_EVENTS intent.

Events::guild_scheduled_event_delete

Typed descriptor for GUILD_SCHEDULED_EVENT_DELETE — a scheduled event was deleted. Delivered under the GUILD_SCHEDULED_EVENTS intent.

Events::guild_scheduled_event_update

Typed descriptor for GUILD_SCHEDULED_EVENT_UPDATE — a scheduled event was updated. Delivered under the GUILD_SCHEDULED_EVENTS intent.

Events::guild_scheduled_event_user_add

Typed descriptor for GUILD_SCHEDULED_EVENT_USER_ADD — a user subscribed to a scheduled event. Delivered under the GUILD_SCHEDULED_EVENTS intent.

Events::guild_scheduled_event_user_remove

Typed descriptor for GUILD_SCHEDULED_EVENT_USER_REMOVE — a user unsubscribed from a scheduled event. Delivered under the GUILD_SCHEDULED_EVENTS intent.

Events::guild_soundboard_sound_create

Typed descriptor for GUILD_SOUNDBOARD_SOUND_CREATE — a soundboard sound was created. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_soundboard_sound_delete

Typed descriptor for GUILD_SOUNDBOARD_SOUND_DELETE — a soundboard sound was deleted. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_soundboard_sound_update

Typed descriptor for GUILD_SOUNDBOARD_SOUND_UPDATE — a soundboard sound was updated. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_soundboard_sounds_update

Typed descriptor for GUILD_SOUNDBOARD_SOUNDS_UPDATE — multiple soundboard sounds were updated at once. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_stickers_update

Typed descriptor for GUILD_STICKERS_UPDATE — a guild's sticker set changed. Delivered under the GUILD_EXPRESSIONS intent.

Events::guild_update

Typed descriptor for GUILD_UPDATE — a guild's settings were updated. Delivered under the GUILDS intent.

Events::integration_create

Typed descriptor for INTEGRATION_CREATE — an integration was created in a guild. Delivered under the GUILD_INTEGRATIONS intent.

Events::integration_delete

Typed descriptor for INTEGRATION_DELETE — an integration was deleted from a guild. Delivered under the GUILD_INTEGRATIONS intent.

Events::integration_update

Typed descriptor for INTEGRATION_UPDATE — an integration was updated in a guild. Delivered under the GUILD_INTEGRATIONS intent.

Events::interaction_create

Typed descriptor for INTERACTION_CREATE — a user invoked a slash command, component, modal, or autocomplete. Not gated by a gateway intent. Most bots should route interactions through App::attach instead of subscribing to this event directly.

Events::invite_create

Typed descriptor for INVITE_CREATE — an invite to a channel was created. Delivered under the GUILD_INVITES intent; the bot also needs the Manage Channels permission on the channel.

Events::invite_delete

Typed descriptor for INVITE_DELETE — an invite to a channel was deleted. Delivered under the GUILD_INVITES intent; the bot also needs the Manage Channels permission on the channel.

Events::message_create

Typed descriptor for MESSAGE_CREATE — a message was sent. Delivered under the GUILD_MESSAGES or DIRECT_MESSAGES intent; content, embeds, attachments, and components stay empty in guilds unless the privileged MESSAGE_CONTENT intent is also enabled.

Events::message_delete

Typed descriptor for MESSAGE_DELETE — a message was deleted. Delivered under the GUILD_MESSAGES or DIRECT_MESSAGES intent.

Events::message_delete_bulk

Typed descriptor for MESSAGE_DELETE_BULK — multiple messages were deleted at once. Delivered under the GUILD_MESSAGES intent.

Events::message_poll_vote_add

Typed descriptor for MESSAGE_POLL_VOTE_ADD — a user voted on a poll. Delivered under the GUILD_MESSAGE_POLLS or DIRECT_MESSAGE_POLLS intent.

Events::message_poll_vote_remove

Typed descriptor for MESSAGE_POLL_VOTE_REMOVE — a user removed a poll vote. Delivered under the GUILD_MESSAGE_POLLS or DIRECT_MESSAGE_POLLS intent.

Events::message_reaction_add

Typed descriptor for MESSAGE_REACTION_ADD.

A classic use is reaction roles: subscribe to reaction add and remove events, identify the configured emoji, then update the member role through the REST client. The bot needs the Manage Roles permission, and its highest role must be above the assigned role. Typed subscriptions infer the non-privileged reaction delivery intents when Bot(...) omits an explicit intents value; if intents are explicit, include Intents::guild_message_reactions(). Production handlers should also restrict the configured message and channel IDs and make the add/remove operations idempotent at the application level.

test "install a reaction role feature" {
fn install_reaction_role(bot : @bot.Bot, role_id : @model.RoleId) -> Unit {
bot.on(@bot.Events::message_reaction_add(), (ctx, event) => {
guard event.guild_id is Some(guild_id) else { return }
guard event.emoji.name.to_option() == Some("✅") else { return }
if event.user_id == ctx.ready().user.id {
return
}
ctx
.app()
.http()
.add_member_role(
guild_id,
event.user_id,
role_id,
audit_reason="reaction role",
)
})
bot.on(@bot.Events::message_reaction_remove(), (ctx, event) => {
guard event.guild_id is Some(guild_id) else { return }
guard event.emoji.name.to_option() == Some("✅") else { return }
ctx
.app()
.http()
.remove_member_role(
guild_id,
event.user_id,
role_id,
audit_reason="reaction role removed",
)
})
}

ignore(install_reaction_role)
}

Events::message_reaction_remove

Typed descriptor for MESSAGE_REACTION_REMOVE — a user removed a reaction from a message. Delivered under the GUILD_MESSAGE_REACTIONS or DIRECT_MESSAGE_REACTIONS intent. See Events::message_reaction_add for a worked reaction-role example.

Events::message_reaction_remove_all

Typed descriptor for MESSAGE_REACTION_REMOVE_ALL — all reactions were cleared from a message. Delivered under the GUILD_MESSAGE_REACTIONS or DIRECT_MESSAGE_REACTIONS intent.

Events::message_reaction_remove_emoji

Typed descriptor for MESSAGE_REACTION_REMOVE_EMOJI — all reactions for a single emoji were cleared from a message. Delivered under the GUILD_MESSAGE_REACTIONS or DIRECT_MESSAGE_REACTIONS intent.

Events::message_update

Typed descriptor for MESSAGE_UPDATE — a message was edited (also fired for embed unfurls and other partial edits). Delivered under the GUILD_MESSAGES or DIRECT_MESSAGES intent; content visibility follows the same MESSAGE_CONTENT rule as MESSAGE_CREATE. before is present only when the bot's messages cache is enabled and the previous revision is still within its retention window.

Events::presence_update

Typed descriptor for PRESENCE_UPDATE — a member's presence (status or activities) changed. Delivered under the privileged GUILD_PRESENCES intent.

Events::rate_limited

Typed descriptor for RATE_LIMITED — the gateway rejected a command sent by this shard and reported when it may retry. Not gated by a gateway intent.

Events::ready

Typed descriptor for READY — the initial state after identify completes: the bot user, unavailable guilds, and session resume data. Fired once per session (including after reconnects that re-identify). Not gated by a gateway intent.

Events::soundboard_sounds

Typed descriptor for SOUNDBOARD_SOUNDS — the response to a Request Soundboard Sounds gateway command. Not gated by a gateway intent.

Events::stage_instance_create

Typed descriptor for STAGE_INSTANCE_CREATE — a stage instance (live stage) was created. Delivered under the GUILDS intent.

Events::stage_instance_delete

Typed descriptor for STAGE_INSTANCE_DELETE — a stage instance was deleted. Delivered under the GUILDS intent.

Events::stage_instance_update

Typed descriptor for STAGE_INSTANCE_UPDATE — a stage instance was updated. Delivered under the GUILDS intent.

Events::subscription_create

Typed descriptor for SUBSCRIPTION_CREATE — a premium app subscription was created. Not gated by a gateway intent.

Events::subscription_delete

Typed descriptor for SUBSCRIPTION_DELETE — a premium app subscription was deleted. Not gated by a gateway intent.

Events::subscription_update

Typed descriptor for SUBSCRIPTION_UPDATE — a premium app subscription was updated, e.g. renewed or ended. Not gated by a gateway intent.

Events::thread_create

Typed descriptor for THREAD_CREATE — a thread was created, or the bot was added to a private thread. Delivered under the GUILDS intent.

Events::thread_delete

Typed descriptor for THREAD_DELETE — a thread was deleted. Delivered under the GUILDS intent.

Events::thread_list_sync

Typed descriptor for THREAD_LIST_SYNC — the active threads of one or more channels were synced after the bot gained access to them. Delivered under the GUILDS intent.

Events::thread_member_update

Typed descriptor for THREAD_MEMBER_UPDATE — the bot's own thread member object was updated. Delivered under the GUILDS intent.

Events::thread_members_update

Typed descriptor for THREAD_MEMBERS_UPDATE — users were added to or removed from a thread. With only the GUILDS intent this fires for changes involving the bot itself; the privileged GUILD_MEMBERS intent extends it to all users.

Events::thread_update

Typed descriptor for THREAD_UPDATE — a thread was updated. Delivered under the GUILDS intent.

Events::typing_start

Typed descriptor for TYPING_START — a user started typing in a channel. Delivered under the GUILD_MESSAGE_TYPING or DIRECT_MESSAGE_TYPING intent.

Events::user_update

Typed descriptor for USER_UPDATE — the bot's own user object was updated. Not gated by a gateway intent.

Events::voice_channel_effect_send

Typed descriptor for VOICE_CHANNEL_EFFECT_SEND — someone sent an emoji or soundboard effect in a voice channel. Delivered under the GUILD_VOICE_STATES intent.

Events::voice_channel_start_time_update

Typed descriptor for VOICE_CHANNEL_START_TIME_UPDATE — a voice channel's session start time changed. Delivered under the GUILDS intent.

Events::voice_channel_status_update

Typed descriptor for VOICE_CHANNEL_STATUS_UPDATE — a voice channel's status text changed. Delivered under the GUILDS intent.

Events::voice_server_update

Typed descriptor for VOICE_SERVER_UPDATE — voice server credentials for a pending voice connection (consumed internally by BotCtx::join_voice). Not gated by a gateway intent.

Events::voice_state_update

Typed descriptor for VOICE_STATE_UPDATE — someone joined, left, or moved between voice channels, or a voice state changed (mute, deaf, ...). Delivered under the GUILD_VOICE_STATES intent.

Events::webhooks_update

Typed descriptor for WEBHOOKS_UPDATE — a webhook in a channel was created, updated, or deleted. Delivered under the GUILD_WEBHOOKS intent.

GatewayCtx

pub struct GatewayCtx {
// private fields
}

Gateway-only services passed to event and service handlers after READY.

GatewayCtx::app

The transport-neutral application context for REST access.

GatewayCtx::cache

The cache attached with Bot::attach_cache, or None when no cache is attached.

GatewayCtx::channel_ref

Bind a channel id to the gateway REST client.

GatewayCtx::framework_raw

Access the underlying interaction framework.

GatewayCtx::guild_ref

Bind a guild id to the gateway REST client.

GatewayCtx::join_voice

Join a guild voice channel and wait until its voice transport is ready.

A second call for the same guild returns the registered connection; moving an existing connection to another channel is outside this API. Discord may send no response events when the channel is full and the bot lacks MOVE_MEMBERS; that case raises VoiceError::JoinTimeout.

The bot must connect the main Gateway with the GUILD_VOICE_STATES intent. This method raises VoiceError::MissingIntent before sending Opcode 4 when that intent is absent.

Pass telemetry to observe non-fatal voice gateway and media diagnostics.

GatewayCtx::latency_ms

fn GatewayCtx::latency_ms(self : GatewayCtx) -> Int64?

The latest heartbeat round-trip time for this context's shard. Unlike AppCtx::latency_ms(), this is the exact shard value rather than the mean across shards with measured latency.

GatewayCtx::member_ref

Bind a guild/user id pair to the gateway REST client.

GatewayCtx::message_ref

Bind a message-create event's message to the gateway REST client.

GatewayCtx::ready

The latest READY payload for this gateway session.

GatewayCtx::ref_of_message

Bind a message model to the gateway REST client.

GatewayCtx::resolve_channel

Resolve a channel with a cache-first lookup, including cached threads. Cache misses (including a disabled channels resource) fall back to REST. This favors speed; use channel_ref(id).fetch() when the latest channel state is required. A REST result is deliberately not written back because gateway events are the cache's only mutation entry point.

MessageCreateEvent.channel_type is commonly absent, so resolving the channel makes thread detection straightforward:

let channel = ctx.resolve_channel(event.message.channel_id)

let is_thread = match channel.typ {
AnnouncementThread | PublicThread | PrivateThread => true
_ => false
}

GatewayCtx::shard_raw

Access the underlying gateway shard.

GatewayCtx::shutdown

async fn GatewayCtx::shutdown(self : GatewayCtx) -> Unit

Request a graceful stop. Closing every managed shard wakes the run loop; the task group then waits for already-started handlers before returning.

GatewayCtx::user_ref

Bind a user id to the gateway REST client.

GatewayCtx::wait_for

async fn[T] GatewayCtx::wait_for(self : GatewayCtx, event_type : EventType[T], predicate : (T) -> Bool, timeout_ms? : Int) -> T?

Wait for the next gateway event of event_type that satisfies predicate. The event remains visible to other collectors and registered handlers. Returns None on timeout. The caller must enable an intent capable of delivering the requested event when it is not already subscribed.

GatewayCtx::wait_for_component

async fn GatewayCtx::wait_for_component(self : GatewayCtx, custom_id~ : String, timeout_ms? : Int) ->
ComponentCtx
?

Wait for the next component interaction with an exact custom id.

ShardConfig

pub(all) enum ShardConfig {
Auto
Single(id~ : Int, count~ : Int)
Fixed(count~ : Int)
Range(ids~ : Array[Int], count~ : Int)
} derive(
Debug
)

Selects which Gateway shards this process owns.