moymo,Docs
Skip to content
Components

Using message components ​

Add components to a message with the components field: a list of action rows, each holding buttons or one menu.

A message with two rowsJSON
json
{
  "content": "Pick a game night",
  "components": [
    {
      "type": 1,
      "components": [
        { "type": 2, "style": 3, "label": "Friday", "custom_id": "night:fri" },
        { "type": 2, "style": 2, "label": "Saturday", "custom_id": "night:sat" },
        { "type": 2, "style": 5, "label": "Rules", "url": "https://example.com/rules" }
      ]
    },
    {
      "type": 1,
      "components": [
        {
          "type": 3, "custom_id": "game", "placeholder": "Which game?", "min_values": 1, "max_values": 2,
          "options": [
            { "label": "Hades", "value": "hades", "description": "Roguelike" },
            { "label": "Celeste", "value": "celeste" }
          ]
        }
      ]
    }
  ]
}

Buttons ​

StyleValueNeedsLooks
Primary1custom_idThe accent colour
Secondary2custom_idGrey
Success3custom_idGreen
Danger4custom_idRed
Link5urlGrey, with an arrow. Opens the address; sends no interaction

A button needs a label (up to 80 characters) or an emoji ({ "name": "🎲" }). Set disabled: true to grey it out. A link button's address must be https.

When a member presses a button you get:

What your endpoint receives (shortened)JSON
json
{
  "type": 3,
  "data": { "custom_id": "night:fri", "component_type": 2 },
  "message": { "id": "…", "content": "Pick a game night" }
}

Select menus ​

MenuTypeThe member chooses from
String3Up to 25 options you define: { label, value, description?, emoji?, default? }
User5Members of the server
Role6Roles of the server
Mentionable7Members and roles
Channel8Channels of the server. channel_types narrows the list

Common fields: custom_id, placeholder (up to 150 characters), min_values (0 to 25, default 1), max_values (1 to 25, default 1), disabled. User, role, mentionable and channel menus can have default_values: [ { id, type: "user" | "role" | "channel" } ].

You get data.values: for a string menu the values of the options chosen; for the others the ids chosen, with data.resolved saying what they are. Moymo has already checked that the number chosen is within min_values and max_values, that string values are among your options, and that ids exist in the server.

Answering a press ​

  • Change the message (type 7): { "type": 7, "data": { "content": "Friday it is!", "components": [] } }. Fields you leave out stay.
  • Write a new message (type 4), often with flags: 64 so only the member sees it.
  • Open a form (type 9).
  • Acknowledge (type 6) and edit the message later.

A counter, end to end ​

The two answers of a counter
js
return {
  type: 4,
  data: {
    content: 'Count: 0',
    components: [{
      type: 1,
      components: [{ type: 2, style: 1, label: '+1', custom_id: 'plus' }]
    }]
  }
}
js
// the message arrives in interaction.message
const count = Number(interaction.message.content.split(': ')[1]) + 1
return { type: 7, data: { content: `Count: ${count}` } }

Things to remember ​

  • Components are on the message, and last as long as it does. Keep what you need to continue in the custom_id or in your own storage.
  • Anybody who can send messages in the channel can press its buttons. Check interaction.member and its permissions before you do anything that should be restricted.
  • Edit a message and its components are replaced as you say; components: [] removes them all.
  • A bot's own messages are always readable by the bot, so interaction.message has the content even without the message content intent.

The wiki is for Moymo's members and developers. Something wrong or missing? Use "Suggest a change" on any page.