Bots and webhooks
Three different things live under one tab, and they answer three different questions. This page says which is which, and what each one can and cannot do.
The short version
| You want | Use | Direction |
|---|---|---|
| A program that reads a channel, writes back into it, and moderates it if you let it | A bot account | both ways |
| Another service to drop a message into a channel | An incoming webhook | into Frenz |
| To hear about things happening on Frenz | An outgoing webhook | out of Frenz |
| A person to police your chat | A moderator | neither |
Bot accounts
A bot is a real Frenz account, owned by you, with its own handle and a BOT chip
next to its name. Create it in Creator studio, Bots & webhooks. You get a
token that starts with frz_, shown once and never again, because only its
hash is stored.
A program uses that token as a bearer:
Authorization: Bearer frz_...
What a bot can do
Whatever you ticked, and nothing else. Each capability is a scope, and each scope opens a named list of routes:
| Scope | What it is for | Routes |
|---|---|---|
messages.read |
Read a channel, its pins and its replies | GET /channels/:id/messages, GET /channels/:id/messages/:messageId/replies, GET /channels/:id/pins |
messages.write |
Write into one | POST /channels/:id/messages |
reactions.write |
Add and remove its own reactions | POST/DELETE /channels/:id/messages/:messageId/reactions |
members.read |
Read the member list and who holds which role | GET /communities/:slug/members |
messages.manage |
Delete a message | DELETE /channels/:id/messages/:messageId |
members.moderate |
Hand out and lift timeouts | POST/DELETE /communities/:slug/members/:userId/timeout |
members.roles |
Set which roles a member holds | PUT /communities/:slug/members/:userId/roles |
Everything not in that table is refused, including every route added to Frenz after you read this. The gate is a whitelist, not a blacklist, so a new route is closed to bots the day it is written rather than the day somebody remembers to close it. A leaked token cannot post as you, read a DM, spend anything or touch a setting.
A bot created without naming its scopes gets messages.read and
messages.write. Anything that acts on another person has to be asked for.
A scope is not a permission
This is the part worth reading twice.
A scope says what its owner allows the token to attempt. It grants nothing.
Every route above still asks the community whether that account may do the
thing, exactly as it asks a person: messages.manage on a bot that is a plain
member of your community deletes nothing, because a plain member cannot delete
somebody else's message. Give the bot admin or manager in the community and the
same token starts working there, and only there.
So moderating takes two separate decisions by two different people: you tick the scope, and the community gives the account a role. Neither on its own does anything.
Every moderating act is logged
Timeouts, role changes and deleted messages all write a line into that community's moderation log, naming the bot that did it and who it was done to. The log is in Community settings, Moderation log, and it does not distinguish between a bot and a person because it does not need to: the bot has a name and a handle, and the line says which one.
Taking it back
Three ways, in increasing order of severity:
- Untick a capability. Takes effect on the next request, and the bot keeps running. This is the one you want mid incident.
- New token replaces the old one immediately.
- Delete removes the bot account entirely.
The community can also remove the bot, or take away the role that made it a manager, without the owner being involved at all.
Letting it into a community
The bot is an account, so it has to be a member. Install it by its handle in Community settings, Bots & webhooks. It then reads and writes only in the channels that account can see, under the same permissions any member has.
Rotating and revoking
New token replaces the old one immediately. Delete removes the bot account. Both take effect on the next request, so a token that has leaked stops working the moment you press the button.
Webhooks
Webhooks carry messages and events. They never carry permissions.
Incoming: something else posts into a channel
A community manager makes an incoming webhook, picks a channel and gets a secret URL. Anything that can make an HTTP request posts to it:
POST <the secret url>
{"content": "the build is green"}
The line lands in that channel with a BOT flag on it. There is no token and no account, which is why it can only ever write into the one channel it was made for.
Outgoing: Frenz tells you something happened
Two flavours, and they are separate on purpose:
- Community webhooks (Community settings) send community events:
message.created,member.joined, and so on. - Creator webhooks (Creator studio) send your own channel events: going live, a new sub, fuel, a new follower. Useful for a Discord relay, a stream overlay, or your own bot.
Every delivery is signed. X-Frenz-Signature is an HMAC-SHA256 of the raw
request body, hex encoded, using the webhook's secret. Verify it before you act
on the body, or anybody who learns your URL can tell you whatever they like.
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
Compare the raw body, not a re-serialised object. JSON.parse then
JSON.stringify gives you different bytes and a signature that never matches.
Can an outside bot moderate my community?
Yes, in a community that has made it a manager, and only there.
This used to be no. The reason it was no was that a moderating bot needs three things first: a scope that can be granted on its own, an audit trail naming which bot did what, and a way to take it back mid incident without pulling the whole integration. All three exist now, which is what changed, and each is described above.
What has not changed is that the token alone is never enough. A bot is an account; the community decides what that account is, the same way it decides what any account is. An owner cannot mint a token that moderates somebody else's community, and a community can strip the role back without asking the owner.
Webhooks are still nothing but messages. An incoming webhook can only write into the one channel it was made for. An outgoing one only tells you something happened, after it happened. Neither carries a permission and neither ever will.
And your stream chat is separate: it is moderated by the channel moderators you appoint in Creator studio, Moderators. Community scopes do not reach it.
Automod is separate, and it is already on
Every stored message goes through automod whether a bot wrote it or a person did. That is server side, always on, and not something a bot opts into or out of. It is not a replacement for a moderator, and it does not need one to work.