178 lines
4.4 KiB
Markdown
178 lines
4.4 KiB
Markdown
# Archive Bot
|
|
|
|
An AIO Discord bot foundation for The Mithral Archive. The first module is status monitoring: it checks configured URLs and keeps one live status message updated in the Discord `status` channel.
|
|
|
|
The message uses a summary embed plus one small embed per service, so each service gets its own green or red Discord color bar.
|
|
|
|
It does not need Discord gateway intents or slash commands for the status module. It only needs a bot token, the `status` channel ID, and permission to send/edit its own messages.
|
|
|
|
The bot also includes a small web dashboard for editing monitored services and forcing immediate Discord refreshes.
|
|
|
|
## Discord Bot Setup
|
|
|
|
Create a Discord application and bot in the Discord Developer Portal, then invite it with:
|
|
|
|
```text
|
|
https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=84992&scope=bot
|
|
```
|
|
|
|
Required channel permissions:
|
|
|
|
- View Channel
|
|
- Send Messages
|
|
- Embed Links
|
|
- Read Message History
|
|
|
|
The current `status` channel ID is:
|
|
|
|
```text
|
|
1504278732070981683
|
|
```
|
|
|
|
## Local Setup
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
cp services.example.json services.json
|
|
```
|
|
|
|
Edit `.env` and set:
|
|
|
|
- `DISCORD_BOT_TOKEN`
|
|
- `DASHBOARD_USERNAME`
|
|
- `DASHBOARD_PASSWORD_HASH`
|
|
|
|
Generate the dashboard password hash:
|
|
|
|
```sh
|
|
python3 status_bot.py --hash-password
|
|
```
|
|
|
|
Paste the output into `DASHBOARD_PASSWORD_HASH`. The dashboard does not store a reusable browser token; it uses an HttpOnly session cookie and CSRF token after login.
|
|
|
|
Dashboard auth includes:
|
|
|
|
- PBKDF2-SHA256 password hashing
|
|
- HttpOnly `SameSite=Strict` session cookie
|
|
- CSRF token required for write actions
|
|
- basic failed-login throttling
|
|
|
|
Edit `services.json` with the URLs you want displayed. Keep private/internal URLs out of Git if they should not be shared.
|
|
|
|
Preview the Discord embed payload:
|
|
|
|
```sh
|
|
ARCHIVE_STATUS_CONFIG=services.json python3 status_bot.py --preview
|
|
```
|
|
|
|
Open `preview.html` in a browser to see an approximate Discord-style render. Paste the JSON from `--preview` into the textarea and render it to test changes before sending anything to Discord.
|
|
|
|
Run it:
|
|
|
|
```sh
|
|
python3 status_bot.py
|
|
```
|
|
|
|
Local runs automatically read `.env` from the current directory.
|
|
|
|
For dashboard testing without touching Discord, set:
|
|
|
|
```env
|
|
DISCORD_DRY_RUN=true
|
|
ARCHIVE_STATUS_STATE=state/status-message.json
|
|
```
|
|
|
|
Open the dashboard:
|
|
|
|
```text
|
|
http://127.0.0.1:8787
|
|
```
|
|
|
|
Sign in with `DASHBOARD_USERNAME` and the password you used when generating `DASHBOARD_PASSWORD_HASH`.
|
|
|
|
## Docker Setup
|
|
|
|
```sh
|
|
cp .env.deploy.example .env
|
|
cp services.example.json services.json
|
|
docker compose up -d --build
|
|
```
|
|
|
|
The bot stores the Discord message ID in `state/status-message.json`. Keep that file mounted so the bot edits the same message after restarts.
|
|
|
|
The deploy compose joins your existing reverse-proxy network:
|
|
|
|
```yaml
|
|
networks:
|
|
mediaserver_default:
|
|
external: true
|
|
```
|
|
|
|
If that network does not already exist on the deploy host, create it once:
|
|
|
|
```sh
|
|
docker network create mediaserver_default
|
|
```
|
|
|
|
The dashboard is exposed inside Docker on port `8787` for your reverse proxy. It is not published directly to the host by default.
|
|
|
|
Use this target from your proxy:
|
|
|
|
```text
|
|
http://archive-status-bot:8787
|
|
```
|
|
|
|
For HTTPS behind a reverse proxy, set:
|
|
|
|
```env
|
|
DASHBOARD_COOKIE_SECURE=true
|
|
```
|
|
|
|
Leave it `false` only for direct localhost HTTP testing.
|
|
|
|
For direct local Docker testing without a proxy:
|
|
|
|
```sh
|
|
docker compose -f compose.yaml -f compose.local.yaml up -d --build
|
|
```
|
|
|
|
Then open:
|
|
|
|
```text
|
|
http://127.0.0.1:8787
|
|
```
|
|
|
|
## Dashboard
|
|
|
|
The dashboard currently supports:
|
|
|
|
- viewing monitored services
|
|
- adding/removing service rows
|
|
- editing check URL, display URL, expected statuses, timeout, and keyword
|
|
- saving `services.json`
|
|
- forcing an immediate check and Discord message update
|
|
|
|
The sidebar leaves room for future modules like polls, webhooks, automations, and service integrations without changing the bot shape later.
|
|
|
|
## Service Config
|
|
|
|
Each service supports:
|
|
|
|
- `name`: label shown in Discord
|
|
- `url`: URL checked by the bot
|
|
- `displayUrl`: URL linked in the embed
|
|
- `method`: optional, defaults to `GET`
|
|
- `timeoutSeconds`: optional, defaults to `10`
|
|
- `expectedStatuses`: optional list such as `["200-399"]` or `[200, 204]`
|
|
- `keyword`: optional text that must appear in the response body
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"name": "Jellyfin",
|
|
"url": "https://jellyfin.mithraic.cloud/health",
|
|
"displayUrl": "https://jellyfin.mithraic.cloud",
|
|
"expectedStatuses": ["200-399"]
|
|
}
|
|
```
|