Zrzur Developers

Buttons, menus and forms

Put buttons and select menus on a message, lay out content in blocks, and ask for input with a form. Only bots can send components.

You will need

The INTERACTIONS intent. Each click arrives as an InteractionCreate of type Component, and each form as ModalSubmit. Both have the same 3 seconds as a command: see the time limits.

Buttons

A message has components, a list of blocks. An ActionRow holds up to five buttons, or one select.

{
  "content": "Heads or tails?",
  "components": [
    {
      "type": "ActionRow",
      "components": [
        { "type": "Button", "style": "Primary", "label": "Heads", "custom_id": "flip:heads" },
        { "type": "Button", "style": "Secondary", "label": "Tails", "custom_id": "flip:tails" },
        { "type": "Button", "style": "Link", "label": "Rules", "url": "https://example.com/rules" }
      ]
    }
  ]
}
FieldMeaning
stylePrimary, Secondary, Success, Danger, or Link
labelUp to 80 characters. A button needs a label or an emoji
emojiUp to 32 characters, no spaces
custom_idUp to 100 characters, sent back to your bot, unique in the message. Not with Link
urlOnly with Link. Opens the address and produces no interaction
disabledShown but not usable
restrictWho may use it, see below

Put what you need in custom_id, such as flip:heads or note:3, and it comes back in interaction.component.custom_id. Answer with UpdateMessage to change the message, or Message for a new one.

A thread's first message cannot carry components yet. Start the thread, then send the message with buttons into it; see Channels and webhooks.

Who may click

{ "restrict": { "users": ["USER_ID"], "roles": ["ROLE_ID"] } }

Up to 25 ids each. The server refuses clicks from anyone else, so your bot never sees them. Not for Link buttons, or for fields in forms.

Select menus

typeOffersExtra fields
StringSelectYour own listoptions, 1 to 25
UserSelectMembersdefault_values
RoleSelectRolesdefault_values
MentionableSelectMembers and rolesdefault_values
ChannelSelectChannelsdefault_values, channel_types

All take custom_id, placeholder (up to 150), min_values and max_values (0 to 25, default 1), disabled and restrict.

An entry of options has label and value (each up to 100, one line), and may have description, emoji and default. Values are unique.

{
  "type": "ActionRow",
  "components": [
    {
      "type": "StringSelect",
      "custom_id": "colour",
      "placeholder": "Pick a colour",
      "options": [
        { "label": "Red", "value": "red" },
        { "label": "Blue", "value": "blue" }
      ]
    }
  ]
}

The choice arrives in interaction.component.values. Users, roles and channels also come as objects in interaction.component.resolved.

Layout blocks

typeFieldsShows
ActionRowcomponentsButtons or one select
TextcontentMarkdown text
Sectiontext (1 to 3), button or thumbnailParagraphs with something at the end
Galleryitems (1 to 10)Images in a grid
Fileattachment, spoilerA file of this message, in place
Separatordivider, spacing (Small, Large)A gap
Containercomponents, accent (#RRGGBB), spoilerA card around other blocks

An image has either url or attachment (the id of a file on the same message), and may have description and spoiler. Containers do not nest.

Limits of a message

WhatLimit
Rows at the top level, and inside one container5
Blocks and components together, nested ones included40
Buttons in a row5
All text of Text and Section blocks together4000

Clients that do not know a block skip it. Webhooks of no bot can post only blocks nobody can use: text, images, link buttons.

Forms

A form, or modal, opens on the person's screen as the answer to a command or a click. It cannot be the answer to another form, or to autocomplete.

{
  "type": "Modal",
  "modal": {
    "custom_id": "note-form",
    "title": "New note",
    "components": [
      {
        "type": "Field",
        "label": "Title",
        "description": "Short and clear.",
        "component": {
          "type": "TextInput",
          "custom_id": "title",
          "style": "Short",
          "max_length": 80
        }
      }
    ]
  }
}

title has up to 45 characters. A form has up to 5 fields, and up to 10 blocks with Text. A Field has label, description (up to 100) and one component:

component.typeFieldsValue arrives in
TextInputstyle (Short, Paragraph), placeholder, required, min_length, max_length (up to 4000), valuevalue
RadioGroupoptions (up to 10), requiredvalue
CheckboxGroupoptions (up to 10), min_values, max_values, requiredvalues
Checkboxdefaultchecked
FileUploadmin_values, max_values (up to 10), file_types, requiredvalues, file ids
A selectas abovevalues

required is true unless you say otherwise. file_types lists image, video, audio or an extension such as .pdf.

When the person sends the form you get an interaction of type ModalSubmit:

{
  "custom_id": "note-form",
  "fields": [{ "custom_id": "title", "value": "Hello" }]
}

Answer it within 3 seconds. UpdateMessage works only if the form was opened from a button.

A person can close a form and your bot hears nothing, so do not wait for it.

Common errors

ErrorCauseFix
FailedValidationA limit or a rule; error says whichFix the components
InvalidOperationModal as the answer to a formAnswer with Message
IsBotA bot tried to clickOnly people use components

Next