Concepts
How a bot relates to people and rooms on Qivuna. Read this before your bot joins rooms you don't own.
Bots are not members#
A bot is never a member of a group or a channel. It is in a room only through a grant: a record that an admin added this bot, with these rights, in this mode. That has consequences you will notice:
- Bots do not appear in member lists or member counts, and never hold an admin role.
- Every right is explicit. A bot without
can_sendcannot write in a group, whatever else it may do. - A group switched to “only admins can send” refuses bots too (403
forbidden_right,parameter: can_send): a bot is never an admin. - Bots cannot add anybody to a room. They can create invite links, which people use themselves.
- Bots never act against the room's owner, its admins or other bots (403
target_protected).
Only the room's owner and admins can add a bot, change its rights or remove it.
Grants, rights and consent receipts#
When an admin adds a bot, the app shows exactly what it will be able to do (“This bot will be able to: …”) and what it will never see. Confirming creates, in one step:
- the grant, with its rights;
- an immutable consent receipt: who added which bot, where, with which rights, in which mode, whether the bot's privacy mode was on and whether it was verified, and the wording version the admin saw;
- a visible line in the room, e.g. “🤖 Dana added @poll_bot · can: send · reads: only messages addressed to it”;
- a
my_chat_memberupdate to the bot withnew_status: "member", therights, themodeand theconsent_receipt_id.
Every later change of rights, and the removal, does the same: a new receipt, a line, an update. Every member of the room can read the receipts of the bots in it. Receipts are never edited.
The rights, which ones can be granted where, and their defaults are on Moderation and rights. Your bot can suggest the rights it needs with setMyDefaultAdministratorRights; the admin decides.
Privacy mode#
Privacy mode is on for every new bot. In a group, a bot in privacy mode receives a message only if:
- it starts with
/command@your_bot(case-insensitive); - it starts with a bare
/commandand your bot is the only bot in the room whose command list (in any scope that applies to the room, any language) contains that command — or no bot advertises it and yours is the only bot in the room; - it mentions
@your_bot; or - it replies to a message your bot sent.
The message's command.addressed_to_me is true for (a) and (b).
A bot receives every message of a group only when both are true: the bot's privacy mode is off (QivBot → Privacy), and an admin granted it can_read_all, which exists only in public groups and is shown to the admin in red. Members see “🤖 1 bot can read all messages here”. In channels, bots receive every post.
Whatever the settings, a bot never receives: messages sent by any bot (its own included), end-to-end encrypted messages (except those sealed to it), messages in secret chats, disappearing messages, and the app's system lines. It gets my_chat_member and chat_member updates instead of system lines.
What a bot learns about people#
Every object a bot receives is built from an allow-list. About a person, a bot can get:
- a pseudonymous
id(below); first_nameandlast_name, as members of a shared room already see them (“Qivuna user” when blank);username, only if the person lets others find them by username;- in encrypted updates, the person's public key for your bot's namespace (
e2ee_key).
Never: phone numbers, e-mail, last seen, profile covers, contacts, the person's other chats, or any internal id.
Pseudonymous ids#
The ids your bot sees for people, chats and messages are not Qivuna's internal ids. Each is a keyed permutation of the internal id under your bot's id namespace, a random value created with your developer account:
- All bots you create share your namespace, so they see the same ids for the same person and room. A bot transferred to a new owner keeps its namespace.
- Another developer's bots see different ids for the same person. Ids cannot be matched across developers.
- An id that does not belong to your namespace, or names a room your bot is not in, answers
404 chat_not_found(ormessage_not_found,user_not_found). The answer is the same whether the thing does not exist or is not yours.
| Id | Range |
|---|---|
A person (User.id; also the id of the private chat with them) | positive, from 252 up to 253 |
A group or channel (Chat.id) | negative, from −252 down to −253 |
A message (message_id) | positive, from 252 up to 253 |
| A bot | its bot number, 7000000001–7999999999 (never pseudonymised) |
All of them are exact in a JavaScript number. Store them as 64-bit integers.
One-to-one chats#
- A person starts a bot by pressing Start (from its profile or a start link). The bot gets
bot_started. Before that,sendMessageto them answers403 user_not_started. - Stop and block in the app gives the bot
bot_blocked; sends then answer403 user_blocked_bot. Starting again clears it. - A message is solicited when the person wrote to the bot, pressed one of its buttons or pressed Start within the last 24 hours. Other messages count against a daily cap per person: 3 (
new), 10 (standard), 50 (verified) — then403 unsolicited_limit. - Push notifications: after 10 pushes from one bot to one person in an hour, further messages arrive silently. Messages from plain bots show a preview according to the person's settings; encrypted bots' messages show only “New message”.
Bot status#
status | Meaning |
|---|---|
development | New; see Development mode. |
active | Published. |
restricted | Reads only: every write answers 403 bot_restricted. Set only by the Qivuna team (never by reports alone); its invite links stop working meanwhile. |
suspended, banned | Every call answers 403 bot_suspended. A ban also removes the bot from every room, revokes its tokens and invite links and switches its webhook off. |
deleted | Gone. The username stays reserved for 30 days. |
Transferring a bot#
An owner can offer a bot to another developer from QivBot; the recipient must accept within 24 hours and meet the creation requirements. On transfer: every token is revoked, the webhook is switched off and its URL and secret are cleared, waiting updates are deleted, the blue check is removed, and every room grant loses the owner-bound rights (can_read_all, can_delete_messages, can_restrict_members, can_ban_members, can_pin, can_invite) until an admin grants them again. Each room gets a line saying the bot has a new owner. For an encrypted bot, the previous owner signs the revocation of its key as part of the offer, and the new owner certifies a new one.
The staged rollout and the kill switch#
Bots open in stages: Qivuna staff and invited people first, then a growing share of users, then everyone. While that runs:
- A person outside the rollout cannot see, start or add bots, and a 1:1 call naming them answers
chat_not_found. - Room content is not filtered per person: in a room where your bot has a grant, everyone's messages reach it under the normal privacy rules.
- Qivuna can pause the whole platform at once. Every method then answers
503 platform_paused, nothing new is queued for bots, and webhook deliveries stop. Back off and try again later.
Old versions of the app cannot start bots or chat with them; people are asked to update.