Groups and access
A group is authorized for a bot when its chat id sits in allowedGroups, in the bot’s admin_groups, or is inherited from a migrated ancestor chat. Which features actually check that is decided feature by feature, not once for the whole bot.
What “authorized” means
collect_authorized_group_ids is the set a chat id needs to land in: the bot’s allowedGroups (memebot.json, read at runtime as allowed_chat_ids), plus bot_state["admin_groups"], plus any chat inherited through bot_state["migrated_chat_ids"] when a basic group upgrades to a supergroup and gets a new id.
is_authorized(ctx) — the check most Telegram-facing features actually call, directly or indirectly — passes on any one of three independent conditions.
The three branches of is_authorized
| Setting | Value |
|---|---|
| Owner or platform admin | Passes in any chat at all, regardless of that chat’s own authorization. |
| DM-authorized username | Passes only in a private chat, for a username on this bot’s DM-authorized list. |
| Allowed chat id | Passes in the chat itself, for anyone in it — matched on chat id alone, group or supergroup only. |
The general allowlist itself has no maximum size, on the dashboard or from /menu’s Manage Groups picker.
How a group gets authorized
Four ways in
| Path | Who | Where |
|---|---|---|
/authorize | Owner or platform admin acts; anyone else’s attempt is only recorded as discovered | In the chat itself |
/getid | Anyone can run it; it additionally authorizes when the sender is the owner or a platform admin | In the chat itself |
The /menu Manage Groups picker | Owner or platform admin | Telegram, via /menu |
| The dashboard Groups tab | Owner | memescale.ai/dashboard |
/authorize
Sent by the owner or a platform admin, /authorize authorizes the current chat immediately. Sent by anyone else, it does nothing but silently record the chat as discovered — no reply, no authorization.
In a private chat it replies Authorized for edits. immediately, then authorizes in the background.
In a group it authorizes and checks the bot’s own admin status at the same time, then replies Authorized (<chat_id>). — with an extra line, To unlock image editing and full functionality, promote me to admin in this group., appended when the bot isn’t an admin there yet.
On failure: a transient Couldn't authorize this group — please try again.
/getid
Anyone can send /getid, in any chat. It always replies with the plain numeric chat id and records the chat as discovered. When the sender is the owner or a platform admin, the chat is additionally authorized in the same step — a second, quieter path into allowedGroups that doesn’t look like an authorization command at all.
One exception: a platform admin sending /getid in a private chat that isn’t the bot owner’s own DM instead adds that chat to the bot’s admin_groups and gets the reply Approved — no discovery record, no allowedGroups entry.
The /menu Manage Groups picker
Tapping a row in the picker behind /menu → Manage Groups authorizes or removes that one group. Full mechanics — the row format, Add Groups, every refusal text — are covered where the picker is introduced.
The dashboard Groups tab
“Discovered Groups” opens a modal listing chats the bot has seen but hasn’t authorized yet — a live merge of the bot’s own discovered list and its current admin memberships, with already-authorized chats filtered out. Select any number and tap Authorize (n).
“Authorize A DM” opens a single-field modal for pre-authorizing one Telegram username for DM generations — see DM authorizations below.
/start in the owner’s own DM also authorizes that DM automatically, the first time, as a side effect of pinning the owner’s user id.
Note
A private Telegram invite link (
t.me/+…,/joinchat/…,tg://join?invite=…) can never be resolved by a bot account — Telegram’s own MTProto call for it answersBOT_METHOD_INVALID./getid, sent inside the group itself, is the way in for a group reached only through a private invite link — for the general allowlist and for the buy bot’s own target list alike.
How one is removed
Two ways out
| Path | Action |
|---|---|
The /menu Manage Groups picker | Tap a ✅ row to flip it to ❌ and remove that group |
| The dashboard Groups tab | Trash icon on the group’s card, then confirm |
Dashboard confirm modal, titled Remove Group: Are you sure you want to remove {name} from the allowed list? Image generation will be disabled in this chat. Buttons Cancel / Remove (busy: Removing...).
Warning
There is no
/deauthorizeor/unauthorizecommand anywhere in the fleet. Removing a group is picker- or dashboard-only.
With zero authorized chats, the dashboard shows: No chats are authorized. Image generation is currently disabled for this bot.
DM authorizations
A DM authorization pre-clears one Telegram username for the same access an allowed group gets, but only inside that username’s own private chat with the bot — never in any group — and it doesn’t let that username authorize anything else.
DM-authorized usernames
| Setting | Value |
|---|---|
| Format | ^[a-z0-9_]{5,32}$, after trimming, stripping a leading @, and lower-casing |
| Cap | 50 per bot |
| Configured from | Dashboard only — Groups tab → Authorize A DM. No Telegram command creates one. |
Dashboard info text, verbatim: “The telegram username you enter will be authorized for generations in DMs. The user will not be able to authorize other groups. You can revoke their permissions at any time, and that change takes effect immediately.”
Revoke from the same tab’s trash icon. Confirm modal: Are you sure you want to revoke @{username}? They will lose DM access on their next message. Buttons Cancel / Revoke (busy: Revoking...).
The dashboard Groups tab
On-screen title: Allowed Groups. Subtitle: “{owner} can send /authorize to instantly unlock {bot} anywhere. Anyone can send /getid to discover a chat, but only you can authorize them below.”
The four row kinds
| Kind | Source | What it means | Removable |
|---|---|---|---|
| Allowed | allowedGroups in memebot.json | In the allowlist that every allowlist-consulting feature checks — see What the allowlist gates. | Yes |
| Demo | demoGroups on the bot record | Shown with a Demo badge; not part of allowedGroups. Demo sends are restricted to platform-admin DMs and never reach a group, whatever is listed here. | No — no remove button |
| Discovered | Live from the bot’s own webhook server | Chats the bot has seen — via /getid or plain membership — not yet authorized. Never shown in the main list; only inside the Discovered Groups modal, with already-allowed chats filtered out. | n/a — authorize it or leave it |
| DM authorizations | dmAuthorizations in memebot.json | See DM authorizations above. | Yes |
Empty state, only when the allowed, demo, and DM lists are all empty: No authorized chats yet. Click "Discovered Groups" or "Authorize A DM" to get started.
What the allowlist gates
A comment inside the /menu root menu’s own code describes allowedGroups as a list “every feature reads.” Read against the features themselves, that isn’t so: each one that cares about group authorization checks it independently, at its own call site, and several never check it at all.
There’s no single gate for it either. _dispatch_webhook — the function every incoming message passes through — has no one check that authorizes or refuses a chat before anything else runs; each step downstream decides for itself.
Consults the group allowlist
| Feature | How |
|---|---|
| Image generation and image edit | _pre_generation_check calls collect_authorized_group_ids directly and refuses the chat if it isn’t in the set (and the sender isn’t a DM-authorized username). |
/raid | if not is_authorized(ctx): return before anything else runs. |
MP3 download — both /download / /mp3 and the auto-detected link path | Both call sites check is_authorized(ctx). |
| Emoji pack creation | Checked at the dispatcher call site: is_authorized(ctx), and — in a group only — the Emoji Packs in Groups switch as well. |
| X automation delivery | Each automation’s target chat id is filtered through collect_authorized_group_ids before a post goes out. |
Does not consult the group allowlist — gated only by its own feature switch, or not gated at all
| Feature | Gated by instead |
|---|---|
/holders | Nothing — no is_authorized call anywhere in the module. It works in any chat the command works in at all. |
| The multi-chain scanner (pasting a contract address) | Only the scanner switch (scanner.enabled). |
/mycalls, /viewallcalls, /leaderboard | Only the scanner switch. |
| Buy bot posting | Its own target list, bots[].buyBot.targetGroupIds — see The buy bot’s separate pool below — never the general allowlist. |
| Custom text commands and button commands | Nothing — no authorization check anywhere in their matching or dispatch. |
Authorization is decided per feature, not once at dispatch. Where a feature does check the allowlist and the check fails, the outcome is silent — the message is consumed and nothing is sent back.
The buy bot’s separate pool
The buy bot keeps its own list of posting targets — memebot.json → bots[].buyBot.targetGroupIds — entirely separate from allowedGroups. Capped at 10: MAX_TARGETS in the bot’s buy-bot controller and MAX_TARGET_GROUPS in the dashboard’s buy-bot service are both 10.
Sending /enablebuybot in a group writes to both lists in the same step: it authorizes the group on the general allowlist, and adds it as a buy-bot posting target.
Warning
Removing a group from the allowlist — from the
/menupicker or the dashboard Groups tab — does not remove it from the buy bot’s target list, and does not stop buys from posting there. The two lists are independent; only the buy bot’s own Manage Groups (/buybotgroups, or the settings card’s Manage Groups button) removes a buy-bot target.