Zrzur Developers

Slash commands

Register commands that people type as /name, with options, sub-commands and names in their language.

You will need

Your bot token (YOUR_BOT_TOKEN) and its id (YOUR_BOT_ID). The bot's id is shown in the Developer Portal, and in GET /users/@me as _id.

Global or per server

ScopeRouteReaches
GlobalPUT /applications/{application_id}/commandsEvery server with the bot
ServerPUT /applications/{application_id}/servers/{server_id}/commandsOne server

A change reaches people at once in both scopes. Use a test server while you build, so that people elsewhere do not see half-finished commands. The bot must be installed in that server.

If the same name exists in both scopes, people see both.

Register

PUT replaces the whole list. It is the easiest way to keep commands in step with your code: send your list every time the bot starts. Unchanged commands keep their ids. Commands you left out are deleted.

curl -X PUT "https://api.zrzur.com/applications/YOUR_BOT_ID/commands" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '[{ "name": "ping", "description": "Check that the bot is awake" }]'

POST /applications/{application_id}/commands adds one command, PATCH /applications/{application_id}/commands/{command_id} changes one, DELETE removes one. Without code, open your application in the Developer Portal, tab Commands: a form adds, changes and deletes commands, with options, choices, names in other languages and who may use them, and shows a preview. Import JSON and Export JSON there take and give the same list as PUT. Saving in the portal replaces the global list, like PUT, so a bot that sends its list at start-up overwrites what you saved.

A command

FieldMeaning
name1 to 32 lowercase letters of any script, digits, - or _
description1 to 100 characters. Required for slash commands, empty for the two menu types
typeChatInput (default, the / command), User or Message (see below)
optionsUp to 25 options
name_localizationsNames by language
description_localizationsDescriptions by language
default_member_permissionsPermission bits a member needs to see and use the command
nsfwOnly usable in channels marked as mature

The server fills in _id, application_id and version. version changes with each update. A person who still has an older version open gets asked to reload.

Limits

WhatLimit
Slash commands per application and scope100
User commands, Message commands5 each
Options on each level25
Choices of an option25
Name, in characters32
Description, choice name, choice value100
Localised texts per field30
All names, descriptions and choices together, translations included8000

Options

{
  "name": "roll",
  "description": "Roll a die",
  "options": [
    {
      "type": "Integer",
      "name": "sides",
      "description": "How many sides",
      "required": true,
      "min_value": 2,
      "max_value": 100
    }
  ]
}
Option typeThe bot receivesExtra fields
Stringtextmin_length, max_length (up to 6000), choices, autocomplete
Integera whole numbermin_value, max_value, choices, autocomplete
Numbera numbermin_value, max_value, choices, autocomplete
Booleantrue or false
Usera user id
Rolea role id
Channela channel idchannel_types: Text, Voice
Mentionablea user or role id
Attachmenta file id

The rules the server checks when you register:

The server checks required options, limits and choices before your bot sees the interaction. For User, Role, Channel, Mentionable and Attachment the value is an id, and the full object arrives in command.resolved, under users (with members in a server), roles, channels or attachments, keyed by that id.

Files from an option

An Attachment option's value is a file id. The file arrives in command.resolved.attachments:

{
  "type": "Command",
  "command": {
    "name": "report",
    "options": [{ "name": "file", "type": "Attachment", "value": "FILE_ID" }],
    "resolved": {
      "attachments": {
        "FILE_ID": {
          "_id": "FILE_ID",
          "tag": "attachments",
          "filename": "screenshot.png",
          "content_type": "image/png",
          "size": 48213,
          "metadata": { "type": "Image", "width": 1280, "height": 720 }
        }
      }
    }
  }
}

Download it from https://cdn.zrzur.com/attachments/FILE_ID/screenshot.png (the tag, the id and the filename). The command has used the id, so it cannot go into your bot's own message: that answers 404 NotFound. To post the file, send its address, or download it and upload a copy.

Sub-commands

Group actions under one name: /note add, /note list.

{
  "name": "note",
  "description": "Notes for this server",
  "options": [
    { "type": "SubCommand", "name": "add", "description": "Write a new note" },
    {
      "type": "SubCommandGroup",
      "name": "admin",
      "description": "For moderators",
      "options": [
        { "type": "SubCommand", "name": "clear", "description": "Delete all notes" }
      ]
    }
  ]
}

Rules:

The chosen path arrives in the options, and the values inside it:

{
  "name": "note",
  "options": [
    {
      "name": "add",
      "type": "SubCommand",
      "options": [{ "name": "title", "type": "String", "value": "Hello" }]
    }
  ]
}

Names in other languages

Give each text per language. The keys are language tags: ar, de, pt-BR.

{
  "name": "ping",
  "name_localizations": { "ar": "فحص", "de": "pruefen" },
  "description": "Check that the bot is awake",
  "description_localizations": {
    "ar": "تحقق من أن البوت يعمل",
    "de": "Prüfen, ob der Bot läuft"
  }
}

Options and choices take the same fields. Localised names follow the same rules as name, so Arabic letters are allowed. The interaction always carries the base name, so your code has one case per command. It also carries the person's language in locale, so you can answer in it.

Who can use a command

default_member_permissions is a number: add the values of the permissions a member needs, from the permission table. A member without all of them does not see the command, and a request gets MissingPermission. 256 is Timeout Members; Manage Messages (8388608) plus Kick Members (64) is 8388672. In the Developer Portal you pick the permissions from a list instead. Your bot should still check user_permissions: an admin can change roles, and a command is not a security wall for what your bot itself does.

"type": "User" and "type": "Message" show a command in the menu of a user or a message. They have no description and no options, and their name can have capitals and spaces. The target arrives in command.target_id.

Common errors

ErrorCauseFix
FailedValidationA rule above is broken; error says whichFix the list. Nothing was saved
CommandAlreadyExistsPOST with a name in useUse PUT or PATCH
TooManyCommandsLimit reachedDelete commands
UnknownCommandThe id is goneGET the list

Reference

The routes are listed under Answering interactions.

Next