Cookiebot
Features

Owner-only operations

private-chat only and gated on CB_OWNER_ID; /grupos is one paged message instead of v1's one getChat + one sendMessage per group (D11) and /broadcast is a cb-worker fan-out instead of a sleep(0.5) loop on the handler thread (D8); /stop and /restart answer a refusal rather than os._exit-ing one of N replicas - see docs/contracts/x_owner_commands.md; QA authored (9 scenarios)

DoneM3gatewayutil
Triggers/grupos/groups/broadcast/leave/blacklist/unblacklist/stop/restart
v1 scenarios
—
Ported
8
Green
9
Failing
—

private-chat only and gated on CB_OWNER_ID; /grupos is one paged message instead of v1's one getChat + one sendMessage per group (D11) and /broadcast is a cb-worker fan-out instead of a sleep(0.5) loop on the handler thread (D8); /stop and /restart answer a refusal rather than os._exit-ing one of N replicas - see docs/contracts/x_owner_commands.md; QA authored (9 scenarios)

behaviour contractv1 source: COOKIEBOT.py:83-105

What it does

In the bot's private chat, and only for whoever holds CB_OWNER_ID: /grupos (or /groups) prints every group the deployment is in, with a total; /broadcast <message> sends a message to all of them; /leave <chat_id> leaves a group, blacklists it and forgets everything the bot stored about it; /blacklist <user_id> and /unblacklist <user_id> add and remove a user from the global blacklist the join guard reads. Anyone who is not the owner gets no answer at all, in a DM or in a group.

/stop and /restart reply with an explanation instead of doing anything. v1 ran one process on one host, so they meant something; here they would kill one of several interchangeable replicas that the orchestrator would replace seconds later. Restarting the deployment is the orchestrator's verb, not the bot's.

Behaviour that must not change

  • The owner gate is every command's first condition. v1 re-tested msg['from']['id'] == ownerID on each branch, and an unset owner id means nobody — never everybody.
  • Private chat only. None of these work in a group, in either version.
  • The wording is v1's: Auto-left\n<id>, Blacklisted user with ID <id>, Unblacklisted user with ID <id>. They were hardcoded English in v1 and are not translated here.
  • @123 and 123 are the same argument — v1 stripped a leading @ and never actually resolved a username, and neither does this.
  • /leave still forgets the group even if leaving the chat fails. v1 only printed that error; the blacklist row and the deletion happen either way.

Three things deliberately differ, all in docs/contracts/x_owner_commands.md: /grupos answers in one paged message rather than one message per group, /broadcast is queued to cb-worker instead of sleeping on the handler thread, and /leave takes the group's other rows with it instead of orphaning them.

How to verify it

qa/features/x_owner_commands.feature (nine scenarios) drives the real dispatcher against a real groups and blacklist. By hand in the sandbox: set CB_OWNER_ID to your own Telegram id, DM the bot /grupos, then /blacklist 424243 followed by /unblacklist 424243 and again to see the "was not blacklisted" answer. /broadcast hi should answer immediately and the worker log should show one broadcast.queued line with the group count.

On this page