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),/helpand a way to cancel. Telegram's own guidelines recommend supporting/start,/helpand/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 singlechat/chat_member. Admin-only commands go inall_chat_administrators. language_codesets 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=payloadpass 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:
/namewith 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
/helpshould 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 |
| Not applicable | Buttons and lists in messages |
Sources
- Telegram Bot API, setMyCommands and BotCommandScope: core.telegram.org/bots/api#setmycommands
- Telegram, bot features (commands and global commands): core.telegram.org/bots/features#commands
- Discord Developer Docs, application commands: discord.com/developers/docs/interactions/application-commands
- Slack API, slash commands: api.slack.com/interactivity/slash-commands
- Meta for Developers, WhatsApp interactive messages: developers.facebook.com/docs/whatsapp/cloud-api/messages/interactive-reply-buttons-messages
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.