Guide 30

Designing bot commands and menus for Telegram, Discord, Slack and WhatsApp

Commands are your bot's interface. A short, consistent, discoverable command set makes a bot feel finished; a messy one sends users to the help page or away.

Guide4 min readUpdated

Principles that apply everywhere

  • Verbs, short and lowercase. /remind, /cancel, /settings. Avoid synonyms for the same action.
  • Few top-level commands. Group related actions (/reminder add, /reminder list) instead of ten unrelated names.
  • Always provide /start (where it exists), /help and a way to cancel. Telegram's own guidelines recommend supporting /start, /help and /settings.
  • Validate input at the platform level when it can (Discord options, buttons) instead of parsing free text.
  • Plan for two languages if your audience needs it. Most platforms let you localize names or descriptions; see internationalizing bots.

Draft your list once, then generate platform formats with the bot command generator.

Telegram: setMyCommands, scopes and languages

Telegram shows a menu of commands next to the input field. Each command has a command (1-32 characters: lowercase English letters, digits and underscores) and a description.

curl -s "https://api.telegram.org/bot$TOKEN/setMyCommands" \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {"command": "start", "description": "Start the bot"},
      {"command": "remind", "description": "Create a reminder"},
      {"command": "settings", "description": "Language and time zone"}
    ],
    "scope": {"type": "all_private_chats"}
  }'

Useful extras:

  • Scopes show different lists in different places: default, all_private_chats, all_group_chats, all_chat_administrators, or a single chat/chat_member. Admin-only commands go in all_chat_administrators.
  • language_code sets a list for users with that interface language, for example "es". Users with other languages see the default list.
  • Deep links t.me/YourBot?start=payload pass a parameter to /start; build them with the deep link builder.
  • Menu button (setChatMenuButton) can open the command list or a Mini App.

The command list builder outputs both BotFather text and the JSON above. In groups, remember privacy mode.

Discord: slash commands, subcommands and context menus

Discord has three kinds of application commands:

  • Chat input (slash) commands: /name with typed options. Name 1-32 characters, description 1-100 characters, up to 25 options.
  • User commands: appear when right-clicking a user (Apps > Your command).
  • Message commands: appear when right-clicking a message, ideal for "Translate", "Report" or "Save".

Group related actions with subcommands: /reminder add, /reminder list, /reminder delete. A command with subcommands cannot be invoked by itself, so it keeps the top level clean.

{
  "name": "reminder",
  "description": "Manage reminders",
  "options": [
    {"type": 1, "name": "add", "description": "Add a reminder",
     "options": [{"type": 3, "name": "when", "description": "e.g. 10m, 2h, tomorrow 9:00", "required": true}]},
    {"type": 1, "name": "list", "description": "List your reminders"}
  ],
  "name_localizations": {"es-ES": "recordatorio"},
  "description_localizations": {"es-ES": "Gestiona recordatorios"}
}

type: 1 is a subcommand and type: 3 a string option. Use default_member_permissions for admin commands and contexts to allow or block DMs. Implementation details: slash commands in discord.js v14 and the Discord bot in Python guide. The Discord command builder produces valid JSON.

Slack: slash commands

Slack slash commands are declared in the app configuration (or manifest) with a request URL. When a user runs one, Slack POSTs a form-encoded payload, and your app must acknowledge within 3 seconds. For longer work, acknowledge immediately and post the result later with the response_url. With Bolt this is await ack() first, then do the work. Rich replies use Block Kit; try the Block Kit builder and the Slack bots guide.

WhatsApp: no command menu, so use buttons

WhatsApp users rarely type commands, and the Cloud API has no command menu equivalent to Telegram's. Design around interactive messages:

  • Reply buttons: up to 3 buttons under a message, ideal for yes/no or a short menu.
  • List messages: a single button that opens a list of up to 10 rows grouped in sections, for menus with more options.
  • Keywords as fallback: accept a few words like "menu", "help" or "agent", case-insensitive, and answer with the main menu.

Interactive messages are free-form messages, so they can only be sent within the 24-hour customer service window (see your first WhatsApp Cloud API message). Build them in the WhatsApp message builder.

Help and discoverability

  • /help should fit on one screen: each command with one line and an example.
  • Reply to unknown input with a short hint and the menu, not an error.
  • Show the command list after onboarding, not a wall of text at /start.
  • Version your command set: when you rename a command, keep the old one as a hidden alias for a while.

Checklist

Platform Register with Where users see commands
Telegram setMyCommands (or BotFather /setcommands) Menu button and / suggestions
Discord Application commands API (PUT) / picker, Apps context menu
Slack App config or manifest / autocomplete in the composer
WhatsApp Not applicable Buttons and lists in messages

Sources

Related comparisons and tools

Frequently asked questions

How many commands should a bot have?

As few top-level commands as cover the main tasks, often fewer than ten. Group the rest as subcommands or behind buttons.

Can I show different commands to admins?

Yes. Telegram has the all_chat_administrators scope and Discord has default_member_permissions. Always check permissions on the server side too.