ADR-013: One shared requests group, a product prefix, and a guest flow isolated from leads
Who is this for
Section titled “Who is this for”Developers adding a product to the requests group, and anyone changing bot routers.
- Several products post requests into one Telegram group. Each product owns a prefix; this one owns
stickers_. - Guest and admin handlers work only in private chats; the leads router works only in the configured group.
- Maintenance mode pauses guests but never the leads module.
- Status: accepted.
Context
Section titled “Context”The sales team wants one place to see requests from every product of the line. That group therefore contains bots of several products. Two bots answering the same command, or one bot reacting to another product’s button, would be chaos.
The sticker bot is also the guest-facing bot. Once it is a member of a group, a /start typed there would begin the
guest flow in front of everyone, and /stats or /pause would answer in public.
Decision
Section titled “Decision”Prefix everything visible in the group — commands /stickers_stats, /stickers_new, /stickers_lead,
/stickers_export, /stickers_forget; callback data stickers_lead:<id>:<status> and stickers_pick:*; the lead
hashtag #stickers_<id>; the request header X-Stickers-Leads-Secret.
Isolate by chat (bot/main.py,
build_dispatcher):
- The maintenance middleware is installed first and acts only on private chats.
- Routers
maintenance,start,consentandadminaccept private chats only. - The leads router accepts only the chat
LEADS_CHAT_ID, and only users inLEADS_ADMIN_IDS. Others get “no access” on a button and silence on a command. - A last fallback router answers
stickers_lead:buttons nobody handled (module off, card from another chat), so a button never spins forever.
Limit the menu. The command menu is registered with the scope “administrators of this chat”, so only group admins see it.
One switch. LEADS_ENABLED=0 removes the router and the loop and makes /leads answer 404; guests are not
affected.
Alternatives considered
Section titled “Alternatives considered”| Alternative | Why not |
|---|---|
| A separate group per product | The team loses the single inbox. |
| A separate “leads bot” per product | One more token to manage; the product bot is already running. Reconsider when a shared leads service is extracted — see the playbook. |
Unprefixed commands addressed with @bot |
Works until someone forgets the suffix; prefixes are unambiguous in menus, logs and search. |
Consequences
Section titled “Consequences”- People in
LEADS_ADMIN_IDSshould also be Telegram admins of the group, or they will not see the menu (typed commands and buttons still work). - The bot should be an admin of the group. Without it, Telegram’s privacy mode hides commands that lack the
@botsuffix. - Every member of the group — including other products’ bots that can read messages — sees the contact data on the
cards.
LEADS_CARD_PII=0switches to masked cards. - A new product must pick its own prefix and repeat this isolation.
Evidence
Section titled “Evidence”docs/LEADS_TZ.md, sections 1, 6, 8.tests/test_leads_wiring.py; commits1d8620e,c0955bd.
Where to go next
Section titled “Where to go next”Last verified: 2026-11-13 against ai-sticker-pack@b715418 and ai-stickers-landing@e350ff5.