Interactions
The SDK automatically captures all 6 types of Discord interactions with response latency measurement and error correlation.
6 Interaction Types
| Event Type | Kind | Trigger | commandName Source |
|---|---|---|---|
interaction_slash | slash | isChatInputCommand() | Full path: cmd group sub |
interaction_button | button | isButton() | customId (snowflakes normalized to {id}) |
interaction_select | select | isAnySelectMenu() | customId (snowflakes normalized) |
interaction_modal | modal | isModalSubmit() | customId (snowflakes normalized) |
interaction_context_menu | context_menu | isContextMenuCommand() | commandName |
interaction_autocomplete | autocomplete | isAutocomplete() | Full path: cmd group sub |
How it works
The SDK listens to the interactionCreate gateway event. For each interaction, it classifies the type, extracts the command name, and patches the reply methods (reply, deferReply, editReply, followUp) on the interaction instance to measure response latency. The original methods pass through untouched -- errors are observed but never swallowed.
Collected Fields
All 6 interaction types share the same data schema:
| Field | Type | Description |
|---|---|---|
commandName | string | Command name or normalized customId. For slash commands, includes the full cmd group sub path. |
interactionKind | string | Interaction kind: slash, button, select, modal, context_menu, or autocomplete. |
interactionId | string | Discord interaction snowflake ID (max 32 chars). |
success | boolean | Whether the response completed successfully. |
deferred | boolean | Whether deferReply() was called before the final response. |
latencyMs | number | Total response latency in milliseconds (from interactionCreate to final reply). |
deferMs | number | Time from interactionCreate to deferReply() completion (only when deferred). |
completed | boolean | Whether the response was fully completed (false if timed out after defer). |
timedOut | boolean | true if no acknowledgement was received within 15 seconds. |
shardId | integer | Shard ID (0--32767). |
clusterId | integer | Cluster ID (0--32767), when configured. |
Additionally, each event carries top-level dimension fields:
| Field | Description |
|---|---|
guildId | Server where the interaction occurred |
channelId | Channel where the interaction occurred |
userId | User who triggered the interaction |
The commandName Field
The commandName field has different meanings depending on the interaction type:
Slash commands -- full subcommand path
For slash commands, commandName contains the full path including subcommand groups and subcommands, separated by spaces:
help -- /help
settings language -- /settings language
mod ban user -- /mod ban userThis allows you to see exact subcommand usage in the dashboard rankings.
Buttons, selects, modals -- normalized customId
For component interactions, commandName is the customId with snowflake IDs replaced by {id}:
ticket-close-1234567890123456789 --> ticket-close-{id}
role-toggle-9876543210987654321 --> role-toggle-{id}This normalization ensures that dynamic IDs are grouped together for meaningful analytics.
Autocomplete -- same as slash
Autocomplete uses the same cmd group sub path as slash commands, since autocomplete is tied to a specific command.
Response Lifecycle
The SDK tracks the complete response lifecycle:
interactionCreate
|
+-- reply() called?
| +-- resolves: success=true, latencyMs=elapsed
| +-- rejects: success=false, command_error emitted
|
+-- deferReply() called?
| +-- resolves: deferMs recorded
| | +-- editReply()/followUp() called?
| | +-- resolves: success=true, latencyMs=total
| | +-- rejects: success=false, command_error emitted
| +-- rejects: success=false, command_error emitted
|
+-- 15s timeout with no ack?
+-- timedOut=true, success=falseNote
When building command ranking reports, filter by interactionKind = slash (or the specific kind you want). Without filtering, button clicks and select menu interactions are mixed into the rankings by their customId, which may not be meaningful for command popularity analysis.
Correlated command_error Events
When an interaction reply method rejects (throws), the SDK emits a separate command_error event in addition to marking the interaction as success: false. The error event includes:
| Field | Description |
|---|---|
name | Error class name (max 200 chars) |
message | Error message (max 2 KiB) |
stack | Stack trace (max 8 KiB) |
commandName | Same command name from the interaction |
interactionId | Correlates with the interaction event |
phase | Which method failed: reply, deferReply, editReply, or followUp |
Autocomplete Behavior
Autocomplete interactions are emitted immediately with no response lifecycle tracking. Since autocomplete has no reply/defer mechanism, only commandName, interactionKind, interactionId, and shard/cluster IDs are recorded.