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)
| Setting | Value |
|---|---|
| By user id | The sender’s Telegram user id matches the id pinned from the bot owner’s first /start. |
| By owner username | The sender’s username matches the bot’s configured owner username. |
| By platform admin | The sender’s username is on Memescale’s platform-admin username set. |
Telegram group-admin rights don’t count
There is no call to Telegram’s
getChatMemberanywhere in this check. A Telegram group’s own admins — anyone promoted inside that group, however senior — cannot open/menuunless 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 |
Beta
The buy bot is currently in beta, served from the dashboard’s beta tab.
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.
Icon fallback
Menu buttons carry small Telegram custom-emoji icons by default. If Telegram ever rejects an icon for this bot, the bot immediately retries the same render as plain-text buttons and remembers not to try icons again — every later menu render for that bot stays plain text from then on.
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.
Note
A stale link or a hand-crafted callback that points straight at the Image Generation Settings page on a bot with no trigger is silently rewritten back to the root menu, instead of opening or erroring.
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 |
One switch, two flags
Image Captions writes two separate config flags at once from a single switch: the gallery-link button under a generation (
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.
Require Forward Slash also gates edits
This switch isn’t limited to generations. When it’s on, the bot’s edit-prompt extraction refuses to recognize an edit at all — a reply to a photo with a prompt, or a photo sent with a prompt caption — unless the text starts with
/. Turning it on silences bare-word image edits exactly the way it silences bare-word generations.
Same flag, the dashboard’s wording
The dashboard’s equivalent switch (Settings → Features → Slash Required For Generation) carries this tooltip: “When this is on, generating or editing an image in your group only works with a forward slash in front of the command. If your command is
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.” Sameslash_requiredflag 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. |
Beta
X automations are currently in beta.
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.
What the bot replies on tap
| 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.
What you can paste
| 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.
What the bot replies
| 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. |
Limit
This picker enforces no maximum group count. Every row above is the only thing standing between a tap and a newly authorized group.