FrenzOpen Frenz →

Frenz / Developers

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:

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:

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.