LammaDevelopers Open Lamma

Building

Register slash commands, receive them, and answer within three seconds.

Slash commands let people use your app by typing / at the start of the message box. They need the commands scope on the install, which new apps ask for by default.

#Registering commands

Commands use the same JSON shape as Discord's, so command builders from discord.js and discord.py produce valid input. Keys Lamma doesn't use, such as localizations, are ignored.

PUT/v1/applications/@me/commands

Replaces all of the app's global commands. A command keeps its id as long as its name stays the same. Global commands show up in every server at once.

POST/v1/applications/@me/commands

Creates one command, or updates the one with the same name. Answers 201 when created and 200 when updated.

GET/v1/applications/@me/commands

Lists the global commands.

GET/v1/applications/@me/commands/{command_id}

One command. PATCH changes it and DELETE removes it.

PUT/v1/applications/@me/guilds/{guild_id}/commands

The same set of routes exists under /guilds/{guild_id}/ for one server the app is installed in. A server command replaces a global command with the same name in that server.

@me can also be the application's own id.

JSON
{
  "name": "roll",
  "description": "Roll dice",
  "options": [
    { "type": 4, "name": "sides", "description": "How many sides", "required": true, "min_value": 2, "max_value": 100 },
    { "type": 3, "name": "label", "description": "What for", "choices": [{ "name": "Luck", "value": "luck" }] }
  ]
}

#Option types

TypeNameExtra fields
3Stringmin_length, max_length, choices
4Integermin_value, max_value, choices
5Boolean
6User
7Channel
8Role
10Numbermin_value, max_value, choices

Required options come first. Subcommands, autocomplete, attachment and mentionable options aren't supported yet.

#Limits

  • 100 commands globally, and 100 per server.
  • 25 options per command and 25 choices per option.
  • Names are 1 to 32 lowercase letters, digits, - or _. Descriptions are 1 to 100 characters.

#Who sees a command

People see an app's commands in a channel when the app is installed in that server with commands, its bot can see and post in the channel, and they can post there too. Someone who is timed out can't use commands.

#Receiving a command

Lamma checks the options first: types, required fields, choices, ranges, and that each user, role or channel belongs to this server. Only then does it send INTERACTION_CREATE to the app's gateway connection, whatever intents it asked for. If the app isn't connected, the person is told at once.

JSON
{
  "id": "…", "application_id": "…", "type": 2, "guild_id": "…", "channel_id": "…",
  "user": { "id": "…", "username": "noura", "name": "Noura", "avatar_id": null, "bot": false },
  "member": { "nickname": null, "roles": ["…"], "permissions": ["view_channels", "send_messages"] },
  "data": {
    "id": "…", "name": "roll", "type": 1,
    "options": [{ "name": "sides", "type": 4, "value": 20 }],
    "resolved": { "users": {}, "members": {}, "roles": {}, "channels": {} }
  },
  "app_permissions": ["view_channels", "send_messages"],
  "created_at": 1759312800000
}

member.permissions is what the person who used the command may do in this channel, with roles and channel overrides, and app_permissions is the same for the bot. Check member.permissions in commands only some people should use. The SDKs give both as Discord's permission bitfields.

#Answering

Answer every interaction within 3 seconds, either with the answer or with a "thinking" state you fill in later.

POST/v1/interactions/{interaction_id}/callback

Once per interaction. Type 4 answers; type 5 shows that the app is thinking.

JSON
{ "type": 4, "data": { "content": "You rolled 17", "flags": 64 } }
PATCH/v1/interactions/{interaction_id}/messages/@original

For 15 minutes: posts the answer after a type 5, or edits it.

POST/v1/interactions/{interaction_id}/followups

For 15 minutes: sends another message.

  • These calls use the bot token like every other /v1 call. There is no separate interaction token.
  • The answer is a message from the bot, under its own permissions, with interaction: { id, name, user_id }, so people see who used which command above it. Slowmode doesn't hold it back.
  • flags: 64 makes the answer ephemeral: only the person who used the command sees it, and it is never stored. It disappears when they dismiss it or reload.
  • No answer within 3 seconds tells the person the app didn't respond. A late callback answers 400 interaction_already_handled.
  • Each call is checked again when it is made. If the app was removed from the server or lost sight of the channel, the call answers 404.