Docs / Developers / Build / Discord events
BuildSDK 0.10.1

Discord events

These docs are public. To publish a plugin you need a YourBot account: sign in to open the Dev Portal.

Use @plugin.on_event(name) for raw Discord events. Twenty event types are dispatched to plugins:

EventPayload highlights
message_createmessage_id, channel_id, author_id, author_bot, content, created_at
message_editmessage_id, channel_id, content
message_deletemessage_id, channel_id
member_joinuser_id, username, guild_id
member_leaveuser_id, username, guild_id
member_updateuser_id, roles
reaction_addmessage_id, channel_id, user_id, emoji
reaction_removemessage_id, channel_id, user_id, emoji
voice_state_updateuser_id, before_channel_id, after_channel_id, self_mute, self_deaf
interaction_createinteraction_id, interaction_type, command_name, options, custom_id, values, modal_values
channel_createchannel_id, name, type
channel_deletechannel_id, name
channel_updatechannel_id, name
role_createrole_id, name
role_deleterole_id, name
role_updaterole_id, name
reaction_clearmessage_id, channel_id (all reactions removed at once)
thread_createid, name
guild_joinid, name (the bot joined the server)
guild_removeid (the bot left / was removed)

Field availability can differ slightly by delivery path (for example author_bot), so read optional fields defensively with event.get(...).

Note: for slash commands, button clicks, and modal submits use the dedicated decorators below — they're easier than picking through interaction_create.

Message text is capability-gated: without events:message_content the whole payload is reduced to IDs and timestamps — content, author fields and attachments are omitted (interaction fields like options and custom_id are always preserved). The events still fire either way. The 16 core payloads also ship typed shapes you can import for autocomplete — from yourbot_sdk.events import MessageCreate, MemberJoin, … — while the last four (reaction_clear, thread_create, guild_join, guild_remove) are plain dicts.

Delivery guarantees

  • Delivered events arrive at least once: your handler can be called twice for the same event, so make side effects idempotent or guard with ctx.ephemeral.dedup(…). Under extreme load the platform sheds gateway events rather than buffering them, so don't build flows that assume every Discord event reaches you.
  • If a handler raises, the event is marked failed and is not retried — the full traceback lands in your plugin logs. (If the whole worker dies mid-event, the event is re-delivered, up to 5 attempts — one more reason handlers must be idempotent.)
  • 5 consecutive crashes within 5 minutes quarantines the plugin (see the Production tab).
  • Handlers for the same server run on a small thread pool and can execute concurrently. Module-level state shared across handlers must be thread-safe (use threading.Lock).
YourBot docs Reference tables are generated from the code that is running. Ask in Discord Suggest a correction