Message components
Bots attach Discord-shaped components to their messages exactly as on Discord, and a click arrives as INTERACTION_CREATE with the usual token and callback flow, so libraries need no changes. This page covers what GameVox renders, how interactions reach your app, and where the limits differ from Discord.
What works
- Action rows (type 1) holding buttons (type 2, styles 1 to 5) and string selects (type 3). A link button (style 5) opens its
urland never sends an interaction. - Cloud and self-hosted servers. Components are stored with the message and returned on REST reads and in
MESSAGE_CREATE/MESSAGE_UPDATE. Editing a message withcomponents: []removes them. - Every client. The desktop and web client, iOS and Android render buttons and string selects (at most 5 rows of 5 controls per message) and show modals and ephemeral replies.
- Modals (callback type 9) and ephemeral replies (
flags: 64), described below.
A message with a row of buttons and a select:
POST /api/v10/channels/{channel_id}/messages
{
"content": "Next map?",
"components": [
{
"type": 1,
"components": [
{ "type": 2, "style": 1, "label": "Vote", "custom_id": "vote" },
{ "type": 2, "style": 5, "label": "Rules", "url": "https://example.com/rules" }
]
},
{
"type": 1,
"components": [
{
"type": 3,
"custom_id": "map",
"placeholder": "Pick a map",
"options": [
{ "label": "Dust", "value": "dust" },
{ "label": "Nuke", "value": "nuke" }
]
}
]
}
]
} Not supported
- User, role, mentionable and channel selects (types 5 to 8). They are accepted and stored, but clients show them disabled, so they never produce an interaction.
- Components v2 layout components. They are not rendered.
- Premium buttons (style 6). They are shown disabled.
- DMs. Component interactions, modals and ephemeral replies only work in server channels.
Receiving a click
A click arrives as INTERACTION_CREATE with type: 3 (MESSAGE_COMPONENT), carrying data.custom_id, data.component_type and, for a select, data.values. message is the full message that was clicked, components included, whatever intents your bot has. A submitted modal arrives as type: 5 (MODAL_SUBMIT) with the entered values in data.components.
GameVox checks each click against the stored message before your app sees it: the control must still be on the message and enabled, select values must be among its options and within min_values / max_values, and the member must be able to see the channel. A click is delivered only to the app whose bot posted the message.
Interactions are delivered over your bot's gateway connection, or POSTed to your Interactions Endpoint URL if you set one (see OAuth2). Two things differ from Discord in HTTP mode:
- Keep a gateway session connected anyway. GameVox hands each interaction to your app through it before POSTing to your endpoint. With no session connected nothing is delivered, and a member who clicks is told the app is not online.
- The response body is ignored. Answer by calling
POST /interactions/{id}/{token}/callback; a callback returned in the body of the POST reaches nobody.
Responding
Use the usual callback endpoint. The interaction token is valid for 15 minutes.
| Type | Effect |
|---|---|
4 CHANNEL_MESSAGE_WITH_SOURCE | Posts a reply in the channel. With flags: 64 the reply is ephemeral. |
5 DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE | Acknowledges now; the first PATCH .../messages/@original posts the reply. With flags: 64 that reply is ephemeral. |
6 DEFERRED_UPDATE_MESSAGE | Acknowledges with no visible change. @original then refers to the clicked message, so a later PATCH .../messages/@original edits it. |
7 UPDATE_MESSAGE | Edits the clicked message in place, components included. |
9 MODAL | Opens a modal for the member who clicked. |
Follow-ups (up to 5 per interaction, flags: 64 for ephemeral) and GET / PATCH / DELETE on @original and on follow-up messages work as on Discord. Types 4, 5 and 9 and ephemeral replies work for slash commands too; types 6 and 7 need a clicked message.
Ephemeral replies
An ephemeral reply goes only to the member who triggered the interaction, on the sessions they have open, and is marked as visible only to them. It is never written to the channel: it is not in message history or in MESSAGE_CREATE, it is gone when the member reloads, and your app can edit or delete it for 15 minutes. Components on an ephemeral reply work like any others. This is the same on cloud and self-hosted servers.
Modals
- Up to 5 action rows of text inputs (type 4). Anything else in a modal is dropped. Style 1 is a single line, style 2 a paragraph.
- The title and labels are cut to 45 characters and placeholders to 100. An input holds up to 4000 characters.
requireddefaults to true. - GameVox checks the submission against the modal it opened (required fields,
min_length,max_length) before your app sees it. - A modal expires after 15 minutes and can be submitted once.
Limits
componentson one message: 64 KiB of JSON on cloud servers; 128 KiB and 40 top-level components on self-hosted servers. A larger request fails with400.custom_id: up to 100 characters; a control with a longer one cannot be used. Selects: up to 25 values of up to 100 characters each.- Clicks: one component interaction per member per server every 0.7 seconds. A self-hosted server also allows at most 5 clicks per member in 5 seconds. Faster clicks are refused and never reach your app.
- Ephemeral replies and modals: 120 per app for each member in a 15-minute window, counted together. Editing an existing one does not count. Over the limit the request fails with
429. - Ephemeral reply content: up to 4000 characters.