Files
stoat_role_bot/README.md
T
Dawnsorrow 09e3b6ca66
Build and Push Image / build (push) Has been cancelled
Initial commit: Stoat Role Bot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 19:45:26 -06:00

169 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stoat Role Bot
Self-hosted bot for **[Stoat](https://stoat.chat)** (open-source chat platform at [stoat.chat](https://stoat.chat)) that gives members **roles** via **reactions** or **text commands** in server channels.
Stoat is the rebrand of Revolt and uses the same API; this bot works with Stoat and Revolt instances.
## Features
- **Reaction roles**: Users react to a specific message with an emoji to get (or remove) a role.
- **Text commands**: Users run `!role add <name>` / `!role remove <name>` for self-assignable roles; `!roles` lists them.
- **Admin commands**: Configure reaction-role message and assignable role list from the chat (or via `config/roles.json`).
## Quick start (Docker)
1. **Create a bot on your Stoat server**
- In Stoat, open your server → **Settings****Bots** (or equivalent).
- Create a bot and copy its **token**.
- Ensure the bot has **Assign Roles** permission (and that its role is above any roles it should assign).
2. **Configure and run**
```bash
cp .env.example .env
# Edit .env and set STOAT_BOT_TOKEN=your_bot_token
cp config/roles.json.example config/roles.json
# Edit config/roles.json: replace YOUR_SERVER_ID and MESSAGE_ID (see below)
docker compose up -d
```
3. **Server ID**: In Stoat, enable developer mode if available, then rightclick your server → copy ID. Use that in `roles.json` as `YOUR_SERVER_ID`.
4. **Reaction-role message**: Send a message in the channel (e.g. “React to get roles”), then copy that messages ID. Put it under `reaction_roles` in `roles.json` with emoji → role name. When users add/remove reactions, the bot will add/remove the role.
## Configuration
- **Environment**
- `STOAT_BOT_TOKEN` or `REVOLT_BOT_TOKEN` (required): Bot token from your Stoat/Revolt server.
- `PREFIX` (optional): Command prefix (default `!`).
- `CONFIG_PATH` (optional): Path to config dir inside container (default `/app/config`).
- **`config/roles.json`**
- `servers.<SERVER_ID>.reaction_roles.<MESSAGE_ID>`: map emoji (unicode or custom emoji ID) → role name.
- `servers.<SERVER_ID>.assignable_roles`: list of role names that can be used with `!role add/remove`.
Example:
```json
{
"servers": {
"01ABC123DEF456": {
"reaction_roles": {
"01MSG789XYZ": {
"👍": "Notifications",
"🔔": "Announcements"
}
},
"assignable_roles": ["Notifications", "Announcements", "Gamer"]
}
}
}
```
The bot writes updated config when admins use the admin commands below, so the container needs write access to the mounted `config` directory.
## Commands
| Command | Who | Description |
|--------|-----|-------------|
| `!roles` | Everyone | List self-assignable roles. |
| `!role add <name>` | Everyone | Give yourself a self-assignable role. |
| `!role remove <name>` | Everyone | Remove a self-assignable role. |
| `!setreactionroles <message_id> emoji=RoleName ...` | Admin (Manage Role) | Set which message and emoji→role pairs are used for reaction roles. |
| `!setassignableroles Role1, Role2, Role3` | Admin (Manage Role) | Set the list of self-assignable roles (comma-separated names). |
For **custom server emojis** in reaction roles, use the emojis ID in `roles.json` (see Stoat/Revolt docs for how to get it). Unicode emojis (e.g. 👍) can be used as-is.
## Setting up reaction roles in config
1. **Create the message in Stoat**
In the channel where you want reaction roles, send a message (e.g. "React below to get roles"). That message must stay there; the bot will watch reactions on it.
2. **Get the message ID**
In Stoat, enable developer mode if available, then **right-click that message** and copy its ID. It's a long string like `01ABC123MSG456...`.
3. **Edit `config/roles.json`**
Under your server (same `SERVER_ID` you use for `assignable_roles`), add a `reaction_roles` block. The key is the **message ID**; the value is an object mapping **emoji to role name** (role names must match your server's roles exactly):
```json
"reaction_roles": {
"01ABC123MSG456": {
"👍": "FFXIV",
"🎮": "Minecraft",
"🃏": "MtG"
}
}
```
- **Unicode emojis** (👍, 🎮, etc.): use the character as the key.
- **Custom server emojis**: use the emoji's ID as the key.
4. **Save the file.** The bot reloads config on each reaction; restart the container only if needed.
5. **Add the reactions to the message**
Add the same emojis to the message. When users click a reaction they get the role; when they remove it they lose the role.
**Example** for your server (replace `PASTE_MESSAGE_ID_HERE` with the real message ID):
```json
"01KHEGSQZB7HXG0YCKMCA2W5PW": {
"reaction_roles": {
"PASTE_MESSAGE_ID_HERE": {
"👍": "FFXIV",
"🎮": "Minecraft",
"🃏": "MtG"
}
},
"assignable_roles": ["FFXIV", "Ascension", "Tarnished", "Minecraft", "Tabletop", "MtG", "Smash", "Soul Calibur", "Hearthstone", "Degenerate"]
}
```
**Alternative:** An admin can set reaction roles from chat:
`!setreactionroles <message_id> 👍=FFXIV 🎮=Minecraft 🃏=MtG`
## Self-hosted Stoat / custom API URL
If you run your own Stoat (or Revolt) instance, point the bot at your API and WebSocket. Set the client configuration when building the bot (revolt.js accepts a `configuration` object with `revolt` and `ws` URLs). The default in revolt.js is the public Revolt/Stoat API (`api.revolt.chat` / `wss://ws.revolt.chat`). To use a different instance you would need to pass a custom configuration to the `Client` constructor; see [revolt.js](https://revolt.js.org/) and [Stoat developers](https://developers.stoat.chat/).
## Hosting the image on Gitea (automated pull on NAS)
**New to Gitea?** See **[docs/GITEA-SETUP.md](docs/GITEA-SETUP.md)** for a simple step-by-step guide.
To build in Gitea and pull the image on your NAS:
1. **Push this repo to your Gitea** (e.g. `myuser/stoat-role-bot`).
2. **Enable Gitea Actions** and add **Secrets** for the container registry:
- **Settings → Secrets**: `REGISTRY_USER` = your Gitea username, `REGISTRY_PASSWORD` = your password or a Personal Access Token (with package write).
3. **On every push to `main`**, the workflow in `.gitea/workflows/docker.yml` builds and pushes the image to your Gitea Container Registry. The image will be at:
`{your-gitea-host}/{owner}/stoat-role-bot:latest`
(e.g. `gitea.example.com/myuser/stoat-role-bot:latest`).
4. **On your NAS**, use the image from Gitea instead of building locally:
- Create `.env` with `GITEA_IMAGE=gitea.example.com/myuser/stoat-role-bot:latest`, plus `STOAT_BOT_TOKEN`, etc.
- Run: `docker compose -f docker-compose.pull.yml pull && docker compose -f docker-compose.pull.yml up -d`
- To **auto-update**: use [Watchtower](https://containers.dev/run/watchtower) or a cron job that runs `docker compose -f docker-compose.pull.yml pull` and restarts the container.
**Manual push** (from your PC, without Actions):
```bash
export GITEA_REGISTRY=gitea.example.com
export GITEA_OWNER=myuser
./push-to-gitea.sh
```
## Run without Docker
Requires Node.js 22+.
```bash
npm install
cp .env.example .env
# Set STOAT_BOT_TOKEN in .env
export CONFIG_PATH=./config
node bot/index.js
```
## License
MIT.