Commands and scopes
Commands are what people type after a slash. Register them so the app can show them in the “/” menu — and so that a bare /command in a group reaches your bot.
Registering commands#
POST https://bots.qivuna.com/v1/setMyCommands
{"commands": [{"command": "poll", "description": "Start a poll"},
{"command": "results", "description": "Show the results"}],
"scope": {"type": "all_group_chats"},
"language_code": "en"}
command:^[a-z0-9_]{1,32}$, without the slash.description: 1–256 characters. At most 100 commands per list, no duplicates.language_code: empty (any language) or a two-letter ISO 639-1 code.setMyCommandswith[]deletes that list, as doesdeleteMyCommands. Together they allow 10 changes a minute per bot.getMyCommandsreturns exactly the list stored for that scope and language, without falling back to another.
Apps learn about changes by themselves: each change bumps a revision that the bot's profile carries, and rooms the bot is in are told to refresh their menu.
Scopes#
scope.type | Applies to |
|---|---|
default | Everywhere, when nothing more specific exists. |
all_private_chats | 1:1 chats with the bot. |
all_group_chats | Every group the bot is in. |
all_chat_administrators | Admins of groups and channels the bot is in. |
chat | One chat, named by scope.chat_id: a group or channel the bot is in, or a person who started it. |
Telegram's chat_administrators and chat_member scopes do not exist (400). chat_id is accepted only with type: "chat".
Which list the app shows#
The “/” menu takes the person's app language (Hebrew if the app prefers Hebrew, otherwise English) and, for each scope in this order, looks for a list in that language, then a list without a language. The first list found wins:
- 1:1 chat:
chat(this person) →all_private_chats→default - Group:
chat(this group) →all_chat_administrators(if the person is an admin) →all_group_chats→default - Channel:
chat(this channel) →all_chat_administrators(admins) →default
In a room, the menu lists the commands of every bot active there.
Which bot a command in a group reaches#
With privacy mode on, a command reaches your bot when:
- it is addressed by handle:
/poll@pollbot …(case-insensitive); or - it is bare (
/poll …) and your bot is the only bot in the room whose command lists containpoll— counting lists of the scopes that apply to the room (default,all_group_chats,all_chat_administrators, orchatfor this group), in any language. If no bot in the room advertises it, a bare command reaches the bot only when it is the only bot in the room.
So: register every command your bot answers, and expect people to use /command@your_bot in rooms with several bots. A command advertised only for admins (all_chat_administrators) still counts for a member's bare command: the rule decides which bot a command means, not who may use it — your bot decides that.
The message carries command: {name, args, addressed_to_me}: name in lower case, args the rest of the text, and addressed_to_me: true when one of the two rules above matched. A message that reached your bot only because it mentions it or replies to it has addressed_to_me: false.
A command is /, 1–32 letters, digits or _, optionally @handle, at the very start of the message and followed by a space or the end.
Commands in encrypted groups#
In an end-to-end encrypted group, the server cannot read commands. The sender's app decides which attached bot a message is for — /cmd@handle, a bare command advertised by exactly one attached bot, an @mention, or a reply to a bot's answer — shows the person a “🔒 → 🤖 @bot” chip before sending, and sends that one message, encrypted, to that bot only. See Encrypted groups.