Files
Bellhop/README.md
prosolis 8c295d183b Session 5: Dockerfile, config example, README rewrite
Multi-stage alpine Dockerfile builds with -tags goolm so libolm isn't
needed at runtime. Annotated config.example.yaml documents every field
and shows ${ENV_VAR} usage for secrets. README is rewritten for the Go
bot — Python-era web-portal docs are gone.
2026-05-24 20:29:13 -07:00

82 lines
2.6 KiB
Markdown

# Bellhop
A Matrix bot that adds movies, TV, and music to Radarr/Sonarr/Lidarr from chat. Invite the bot to a room, allowlist the room ID, and any member can type `!movie dune` to add the top search hit.
## Command UX
```
!movie <query> — add the top Radarr hit
!tv <query> — add the top Sonarr hit
!music <query> — add the top Lidarr hit
!help — show the command list
```
The bot replies in a thread under the request so a busy room stays readable. No numbered picker, no reaction selector — the top search result is what gets added. If you want something other than the top hit, narrow the query.
## Authorization
Any member of an allowlisted room may issue commands. The bot auto-joins on invite, but the room ID must appear under `matrix.allowed_rooms` in the config before commands are honored.
## Configuration
Copy `config.example.yaml` to `config.yaml` and edit. The loader expands `${ENV_VAR}` references at load time, so secrets can come from the environment.
Required:
- `matrix.homeserver`, `matrix.user_id`, `matrix.password`
- `matrix.allowed_rooms` (at least one room ID)
- At least one of `services.radarr` / `services.sonarr` / `services.lidarr`
Per-service: `url`, `api_key`, `quality_profile_id`, `root_folder`. Lidarr also needs `metadata_profile_id`.
Omit a service block to disable its command — `!movie` with no `radarr` block replies "Radarr is not configured".
**Finding quality profile IDs:**
```bash
curl -H "X-Api-Key: YOUR_KEY" https://radarr.example.com/api/v3/qualityprofile
```
## Running
### Local
```bash
go build -tags goolm -o bellhop ./
./bellhop -config config.yaml
```
The `goolm` tag uses the pure-Go olm implementation so libolm isn't needed.
### Docker
```bash
docker build -t bellhop .
docker run -d \
--name bellhop \
-v "$PWD/config.yaml:/app/config.yaml:ro" \
-v bellhop-data:/app/data \
bellhop
```
The `data` volume holds the Matrix device file and the E2EE crypto store. Losing it forces a re-login and re-verification on next start.
## E2EE notes
The bot bootstraps cross-signing on first run and persists Olm/Megolm sessions in `data/crypto.db`. If you rotate the bot's password or wipe `data/`, the bot logs in as a new device — existing rooms will need to re-share keys, which mautrix handles automatically on the next message.
## Project layout
```
main.go
internal/
config/ — YAML loader with ${ENV_VAR} expansion
matrix/ — mautrix client: login, device persistence, E2EE, sync loop
arr/ — Radarr/Sonarr/Lidarr HTTP clients
bot/ — command parser + dispatch + threaded replies
```
## License
See repository for license details.