The /menu control panel
/menu opens the bot's settings card directly in Telegram: three feature doors, an Extra Features page, and the group picker behind allowedGroups. /options and /help are exact aliases for the same command.
Opening the menu#
Send /menu, /options, or /help in any chat the bot is in — three exact aliases for one command. Matching is case-insensitive, the leading slash is optional, and an @<botusername> suffix is accepted: /menu, menu, /MENU@yourbot all open it.
Who may open it — is_owner_or_admin (any one is enough)
/start.getChatMember anywhere in this check. A Telegram group's own admins — anyone promoted inside that group, however senior — cannot open /menu unless they also match one of the three conditions above. Anyone who doesn't gets no reply from this route at all: no denial message, no error.This check is independent of whether the chat itself is authorized for the bot — the owner or a platform admin can open /menu in any chat the bot is a member of, authorized or not. See Groups and access for what "authorized" means.
Command suggestions in unauthorized chats#
Distinct from the settings card itself: Telegram also lets a bot push a per-chat list of suggested slash commands — the list under the / icon next to the message box. The bot recomputes that list on every incoming message.
When is_authorized — owner/staff, a DM-authorized username, or the chat's own presence in the allowed-groups set, see Groups and access — fails for the sender and chat a message came from, the bot deliberately pushes an empty list for that chat: menu_plan marks the scope none, and sync_menu calls Telegram's setMyCommands with an empty array. Nothing is suggested there — on purpose, not a bug.
This is separate from whether /menu itself works. /menu is gated purely on is_owner_or_admin (see Opening the menu above) and still runs when typed, suggested or not.
The three doors#
The root card's text is exactly View the menu below. Up to three doors follow, one per row top to bottom, then a Manage Groups / Close row at the bottom.
| Door | Opens | Always shown? |
|---|---|---|
| 🎨 Image Generation Settings | The Image Generation Settings page (below) | No — only when the bot has at least one generation trigger. See The generation gate. |
| 💹 Buy Bot Menu | The buy bot's own settings card, replacing this card in place | Yes — injected on every bot, unconditionally. |
| ✨ Extra Features | The Extra Features page (below) | Yes |
Buy Bot Menu is a hand-off, not a settings page of its own here: the tap replaces the settings card with the buy bot's own card. If that card happens to be riding on a media message at the time (a buy-bot layout with an image or video attached), Telegram can't edit media back into plain text, so the bot drops that card and sends the settings page as a fresh message instead of editing in place.
Manage Groups opens the group picker described later in this chapter. Close deletes both the settings card and the original /menu command message that opened it.
Every settings-page button carries an ms: callback prefix; every group-picker button carries om:. Both are gated the same way as the command itself — a tap from anyone but the owner or a platform admin gets the alert Owner / admins only and changes nothing.
The generation gate#
The Image Generation Settings door renders only when the bot has at least one generation trigger. A bot configured with packageType custom — an edit-only / utility bot with no character and no trigger — yields no triggers at all, so the door never appears for it.
Image Generation Settings#
Header text: 🎨 Image Generation Settings. Two switches, in this order, each a label row followed by an On / Off button pair; the page ends with Back / Close.
| Label | Writes | Default |
|---|---|---|
| ✍️ Image Captions | gallery_links_enabled and captions_enabled — both, together | Off |
| ⌨️ Require Forward Slash | slash_required | Off |
gallery_links_enabled) and the caption text under a generation (captions_enabled). The switch itself reads as On whenever either flag alone is On, and tapping it writes the same new value to both./. Turning it on silences bare-word image edits exactly the way it silences bare-word generations.generate, people have to type /generate — typing the bare word does nothing. Turn it on when a trigger word also comes up in normal chat, so an ordinary message never fires an unintended generation." Same slash_required flag either way.Extra Features#
Header text: ✨ Extra Features. Four switches, in this order, same label-then-On/Off shape; the page ends with Back / Close.
| Label | Writes | Default | Write path |
|---|---|---|---|
| 🎵 MP3 Downloader | mp3_enabled | On | Bot state — instant, in-process. |
| 😀 Emoji Packs in Groups | emoji_packs_enabled | On | Bot state — instant, in-process; also re-registers this bot's Telegram command menus. |
| 🐦 X Automation | twitter_automation_enabled | Off | Bot state — instant, in-process. |
| 🔎 Multi-Chain Scanner | scanner.enabled | Off | memebot.json — see below. |
The first three switches write straight to the bot's own state file and take effect immediately, with no round trip anywhere. Multi-Chain Scanner is different: it lives in memebot.json, so the tap dispatches to memescale.ai, which writes the config, pushes it to the bot, and reloads the bot before the tap gets its answer.
| Situation | Reply |
|---|---|
| Already in that state | Already on / Already off |
| Toggled successfully | Updated |
| Multi-Chain Scanner only: the dashboard couldn't be reached | Couldn't reach memescale.ai — try again |
The Manage Groups picker#
Manage Groups opens the same group-picker implementation the buy bot uses for its own target list (see Groups and access) — pointed at allowedGroups instead. Prompt text, with rows to show: Which group should I generate and edit images in? Tap to add or remove.
With no admin groups to show yet, the card reads instead: Promote me to admin in whichever group you'd like me to generate images in, then tap Add Groups.
- One row per group the bot is currently an admin in — rechecked live, capped at scanning 40 groups — where the tapping user is also a member:
✅ Titlewhen authorized,❌ Titlewhen not. Tapping a row flips it and the card redraws in place. - Any group still in
allowedGroupsthat the live admin check can no longer vouch for — the bot was removed or demoted since — still gets a✅row, so it can still be removed even though it can't be re-added by tapping. - Group titles on each row are capped at 48 characters.
Add a group
- Tap
Add Groups. - The card is replaced with:
Let's add a group. Make sure I am in the group as an admin first, and then send me either the link to the group, or the group ID which you can get by typing /getid. - Send a public group link, an
@handle, at.me/c/…message link, or the numeric chat id from/getidas your very next message in that chat. - The bot checks the chat and replies with the outcome below.
| You send | Read as |
|---|---|
A number, 5+ digits, with or without a leading - | Chat id |
@handle | Public handle |
t.me/…, telegram.me/…, telegram.dog/… public link | Public handle |
t.me/c/<id>/… message link | Chat id |
tg://resolve?domain=… | Public handle |
t.me/+…, /joinchat/…, tg://join?invite=… — a private invite link | Refused, see below |
{what} in the replies below becomes "link" or "group ID", matching whichever form you sent.
| Situation | Reply |
|---|---|
| Not a recognizable link or id | That doesn't look like a group link or ID., then the Add Groups prompt again |
| A private invite link | That's a private invite link, and Telegram doesn't let bots look those up. Send /getid inside the group and paste the group ID here. |
| The bot isn't in that chat | I'm not in this group yet, add me first and repaste the {what}. |
| The bot is in the chat but not an admin | I'm in the group but not an admin yet, once I am admin repaste the {what}. |
| The chat is a channel, not a group | That's not a group. Send the {what} of a group I'm an admin in. |
| Already authorized | The picker redraws with <title> is already authorized ✅ on top. Nothing is written. |
| Otherwise | The group is authorized. The picker redraws with Added <title> ✅ on top. |
