Concepts

How a bot gets into a server, what it can see once there, and what Hexis does and does not promise about it.

Install and the managed role

Encryption, in bot terms

A server is end-to-end encrypted only if its owner chose that when creating it (public is the default), and the mode cannot change afterwards. DMs are always end-to-end encrypted. Here is what that means for a bot.

Older apps fail closed. Apps that predate bot support refuse an unknown device-list version instead of guessing, which is why installs wait for the client-version floor (see Install above).

Interactions: commands, mentions and clicks

An interaction is something a member sends to your bot on purpose: a slash command, a mention of a no-read bot, or a click on a button or select on one of its messages. This is the only way a no-read bot hears a member.

A limit we state plainly: no per-interaction forward secrecy. Every interaction is sealed to the bot device’s one long-lived ML-KEM key, and v1 never rotates it. Anyone who recorded the sealed blobs, and who ever gets that key, can open every interaction sealed to it: past ones and future ones. The key lives in the bot’s state directory, and the same key also opens channel seeds, DM setup and voice secrets, so a stolen state directory exposes those too. It is not rotated in v1 because rotating it would strand other members. Protect the state directory like the token, or better. Rotation with a grace window is a future change.

What has shipped. The sealed channel and the runtime support (Interaction events, reply_to_interaction) are in the product. Registering slash commands with the server (register_commands, #1436), the mention hook (#1437) and buttons and selects (#1438) are not arriving: the SDK call exists but answers NotYetSupported. When commands ship, a command will have a name of 1 to 32 characters (a-z 0-9 _ -), a description up to 100, up to 25 typed options, and a bot can register 50 global and 50 per-server commands.

Events and reconnecting

Intents and privileged intents

An intent is a family of events. The default is lifecycle and interactions. The full list is in the reference. Today the runtime filters by intent on the client side.

Server-side intents (#1430). A bot declares its intents when it connects (SubscribeEvents), and the server sends only those, from channels the bot’s role can read. Three intents are privileged: members, presence and message_content (plaintext servers; the reader kind in encrypted ones). The owner switches them on per app, with consent text; for public bots they are also a review field. An app that has been approved holds only the privileged intents that were in the set the reviewer saw; adding one later sends the app back to review. A refused intent is listed in the answer, never silently dropped. Message text and attachments, history included, reach a bot only where it may read them; otherwise the event arrives emptied.

Events sent to a bot are capped at 50 a second with bursts of 200. Past that they are dropped and the socket gets a drop notice once a second (BotEventsDroppedBroadcast), after which the bot should reconcile as after a reconnect. Interactions and lifecycle events are never dropped.

Notices

A notice is a server-authored row in a channel: “Posted by Workflows” or “Webhook <name>”. It is the only way the server itself writes into an encrypted channel. The server side (stored notices and their rate limits) is shipped. The client side arriving is not: the distinct card on all three apps, with no avatar, no member colour, no edit and the chip Not end-to-end encrypted, arrives with #1472, and DM notices with #1474.

Webhooks arriving

Incoming webhooks (#1439) let a service post into a channel without running a bot. They need a new permission bit, MANAGE_WEBHOOKS, off by default, which holders of Manage Server can add to roles. Their posts are notices, so in encrypted servers they are labelled as not end-to-end encrypted. Outgoing, HTTP-delivered bots (#1440) are planned for plaintext servers and metadata events only: with no runtime there is no device, so there is nothing to seal to. This section describes plans; no webhook route is documented because none is public yet.

Safety