Worker bots
Who this is for: developers building moderation / automation tools for open-history groups and Communities, and admins who request installs.
Service (1:1) bots: Bot API · Product: Bots · Console: developers.buzzio.dev
Why two kinds
| Service | Worker | |
|---|---|---|
| Discovery | People search @weather_bot |
Not in people search or 1:1 dashboard |
| Surface | Start → DM | Room Bots tile / /bots |
| Token | Separate | Separate — kind locked at Forge create |
| Install | User Starts | Admin requests → developer Accepts |
One token that can spam every Starter and kick members is a worse leak. Need both jobs? Create two bots.
Never: sealed 1:1, Whisper private chat, Whisper Questions, E2E groups. Never: dump a bot into OHG admin_ids. Never: give a bot Community administrator / manage_roles. Never: install the instant an admin taps Add — Accept on Console first.
Install flow
Person (phone, seed stays there)
↓
Search @forge_bot → /newbot → Worker
↓
display name + @username + API token (copy once)
↓
Not in people search. Not on 1:1 dashboard.
↓
Developer links the worker token on developers.buzzio.dev
↓
OHG or Community → Bots tile → lookup @mod_bot
↓
Admin picks permissions / roles → Request (room shows Pending)
↓
Console → Requests → Accept or Reject
↓
Only after Accept: bot is in the room; server gets events; API checks grants
Pending requests do not count as installed. Reject → bot never joins. Same token cannot Start a 1:1.
Console Requests lists pending for every linked worker (bot name on each card). Accept/reject requires the signed-in developer who linked that bot. The phone Bots screen cannot Accept for the developer.
Who may request, edit, remove
| Room | Who |
|---|---|
| Open-history group | Creator (super admin) or anyone in admin_ids |
| Community | Creator, adminIds, or a role with Administrator |
Members cannot send a request. The developer cannot accept by pasting a token into the room.
Platform `/bots` slash
Admins only. Never forwarded to the worker webhook (or a worker could fake an add).
/bots
/bots add mod_bot
/bots perm mod_bot delete on
/bots remove mod_bot
/bots add is still a request. Members who type /bots get “Only admins can use /bots” and the text is not sent to the room.
Later permission ticks can live on the Bots screen or /bots perm without a full re-Accept for every toggle (product: ticks are live after install).
OHG permissions (checklist)
OHG humans stay binary admins (admin_ids). Bots must not use that list. Grants live on the install, per group, per bot_id.
Default on the request: Read messages + Send messages. Everything else off until ticked.
| Permission | Meaning |
|---|---|
| Read messages | See messages (needed for commands) |
| Send messages | Post as the bot |
| Delete messages | Delete other people’s messages |
| Pin messages | Pin / unpin |
| Timeout / mute | Restrict a member for a time in this OHG |
| Kick | Remove from this OHG |
| Ban | Ban from this OHG — not a global Buzzio ban |
| View members | Member list if the group hides it from members |
| Approve joins | If join approval is on |
If the OHG is admins-only send, Send on the bot still allows it to post (it is a tool, not a member). It still cannot do unticked admin actions.
Community permissions
Do not invent a second permission catalog. Assign existing Community roles on the request (Moderator, Helper, a dedicated “Moderation bot” role, etc.). Channel view/send overrides apply through those roles.
Always off for bots, even if the assigned role has the flag:
administratormanage_roles
UI copy: Bots cannot have Administrator or Manage roles.
Typical v1 role: Ban & remove members, Delete other messages, Pin, View members, Can tag — nothing else.
Private staff channel: grant that bot role view/send on the channel, same as a human. Do not give @everyone dangerous mod perms just to make a bot work — create a bot role.
Hard denials (both rooms)
Hide in the UI. Reject on the server even if a client sends them:
- Super admin / transfer ownership / change creator
- Promote or demote human admins
- Add or remove other bots
- Delete the OHG or community
- Password, security, encryption, history/boot billing
- Community
administratorandmanage_roles - Start a 1:1 / appear in people search
Hierarchy
A worker cannot mute, kick, or ban:
- The room creator
- An OHG human admin (
creator_idoradmin_ids) - A community member whose highest role is ≥ the bot’s highest assignable role
- Another worker
Fail with permission denied, not a silent no-op.
Room power vs bot commands
Room permissions (this page): what Buzzio allows this token to do in this room. Enforced on every API call.
Bot commands (your code): /mute @user 10m is a normal message Buzzio forwards. Your server calls restrictChatMember. If Timeout was not granted, Buzzio returns permission denied.
Buzzio does not ship a platform command language for /mute / /ban. You define commands. Buzzio ships API methods.
Worker Bot API
Same host and token style as Bot API. Every method with a parameter table: Bot API methods. Service tokens get 403 on worker methods even with a guessed chat_id. Worker tokens get 403 on 1:1 botdm_* sends.
Methods require: kind = worker, approved, plan active, linked on Console, accepted in that room, and the matching grant. Pending requests do not count:
| Method | Needs |
|---|---|
sendMessage / media URL sends / sendSticker |
Send (Community stickers also need channel send_sticker) |
deleteMessage |
Delete |
pinChatMessage / unpinChatMessage / unpinAllChatMessages |
Pin |
restrictChatMember |
Timeout |
kickChatMember |
Kick (catalog #140; same grant) |
banChatMember / unbanChatMember |
Ban |
banChatSenderChat / unbanChatSenderChat |
Ban a channel/bot poster — not a ghost_ person |
getChat / getChatMember / getChatAdministrators / getChatMemberCount |
Read (member list: View members if the room hides it) |
leaveChat |
Always (bot leaves this room) |
setChatTitle / setChatDescription / setChatPhoto / deleteChatPhoto |
Manage room info (OHG tick) or Community modify_description |
setChatStickerSet / deleteChatStickerSet |
Room default pack — set must already belong to this bot |
setChatPermissions |
Manage room info — OHG only (can_send_messages, can_see_members) |
setChatAdministratorCustomTitle |
Label on this worker in the room |
setChatMemberTag |
Community only — tag or assign a non-admin role |
setMyDefaultAdministratorRights / getMyDefaultAdministratorRights |
Default worker ticks for new installs. Never administrator / manage_roles |
createChatInviteLink / editChatInviteLink / revokeChatInviteLink / listChatInviteLinks |
Extra invite (OHG Approve joins; Community temp_invite / invite_people) |
getMyPermissions / getMyInstalls / getChatHistory |
Live ticks, accepted rooms, 7-day / 100-message window |
reportMessage |
Staff-visible snapshot (same reasons as in-app Report) |
exportChatInviteLink |
Primary invite (OHG Approve joins; Community invite_people) |
approveChatJoinRequest / declineChatJoinRequest |
Admit or deny ghost_… (OHG Approve joins; Community invite_people) |
answerChatJoinRequestQuery / sendChatJoinRequestWebApp |
Join-gate ack + HTTPS Mini App |
createForumTopic / editForumTopic / deleteForumTopic |
Community channel as a topic (create_channels / edit_channels) |
closeForumTopic / reopenForumTopic |
Freeze posting (edit_channels) |
unpinAllForumTopicMessages |
Clear pins in that channel (pin_messages) |
hideGeneralForumTopic / unhideGeneralForumTopic / closeGeneralForumTopic / reopenGeneralForumTopic / editGeneralForumTopic / unpinAllGeneralForumTopicMessages |
Default / welcome channel |
getForumTopicIconStickers |
Allowed topic icon colors |
Service tokens get 403 on these methods even with a guessed ohg: / community: chat_id.
chat_id is the OHG id or community id — never a sealed person id, never botdm_*. For a specific channel, use community:{communityId}:{channelId} or pass message_thread_id.
Rate limits still apply. Ban is this room, not the person’s Buzzio account.
Events after Accept
Via webhook or getUpdates (after Accept — not when the room only taps Request):
| Event | Notes |
|---|---|
| New / edited / deleted message | If Read granted |
chat_join_request |
Pending join; OHG needs Approve joins, Community needs invite_people |
| Member joined / left | — |
| Bot added / removed | First event in a room is typically bot_added |
| Permissions or roles changed | — |
No 1:1 /start. Remove or leaveChat sends bot_removed and clears the install. Do not expect a dump of room history just because someone requested the bot.
Optional: Console / Forge notice that a request is waiting — that is not a Bot API update.
Privacy label
Shared rooms are already not E2E. Still say it after accept:
This room has a worker bot that can read messages you allow it to see. The bot owner’s server can receive those events.
Show on the Bots screen and once in the room after accept. Pending does not get the label. Missing label after install is a privacy bug.
Troubleshooting
| Symptom | Try |
|---|---|
| Lookup finds nothing | Worker not approved / not linked, or you typed a service bot username |
| Stuck on Pending | Developer must Accept on Console Requests |
| API 403 on room method | Wrong kind (service token), not accepted, or grant missing |
/bots visible to members |
Should not be — report as a product bug if members can install |
Related
- Bot API
- Bot API methods (all 150, individually)
- Developer overview
- Bots (product)
- Groups · Communities
- Sealed vs shared