Issue #2. Search/request now work without Seerr — when seerr.url/api_key are left as placeholders the bot falls back to direct Sonarr/Radarr lookup + add (mirrors how Lidarr music already works). Numbered selection keeps working across both sources via a _source discriminator stamped onto each result. !media requests / !media trending now print a friendly hint when Seerr is absent. base-config.yaml no longer ships any homelab-specific URLs, MXIDs, or Emby UIDs — admin_users defaults to [], user_map to {}, and every service URL uses a docker-hostname placeholder. New per-service config keys (quality_profile_id, root_folder_path, monitor, search_on_add, language_profile_id, minimum_availability) let operators pin Sonarr/ Radarr defaults the same way Lidarr already could; null = auto-pick the first profile/folder. README rewritten as a self-contained setup guide: requirements, build, upload, instance config (Required vs Optional with the Seerr fallback called out), webhook setup, fork notes.
145 lines
5.6 KiB
Markdown
145 lines
5.6 KiB
Markdown
# maubot-media
|
|
|
|
A [maubot](https://github.com/maubot/maubot) plugin that turns a Matrix room into a control surface for the *arr / Plex-style media stack:
|
|
|
|
- **Search & request** via [Jellyseerr / Overseerr](https://docs.jellyseerr.dev/) **or** directly against Sonarr/Radarr.
|
|
- **Library + playback** via Emby (`recent`, `nowplaying`, `watched`, `find`, `resume`, `random`).
|
|
- **Sonarr / Radarr / Lidarr** queue, calendar, missing, music search/add.
|
|
- **Downloads** — NZBGet + qBittorrent activity, completed, speed, pause/resume.
|
|
- **Subscriptions** — `!media subscribe <show>`, with a Sonarr webhook pinging the room when new episodes import.
|
|
- **Daily digest** posted to a notifications room (recently added, completed, queued, plus an optional Sunday recap pulled from an ntfy topic).
|
|
- **Health check** across all seven backing services in one command.
|
|
|
|
Each Matrix user is mapped to per-service IDs in plugin config; unmapped senders get a refusal.
|
|
|
|
## Commands
|
|
|
|
```text
|
|
!media help # full command list
|
|
|
|
# Search & request
|
|
!media search <query> # numbered results
|
|
!media request <query> [--tv|--movie]
|
|
!media request <N> # pick N from the last search/trending
|
|
!media requests # (Seerr only) your pending/processing
|
|
!media trending # (Seerr only) what's trending
|
|
|
|
# Library & playback (Emby)
|
|
!media nowplaying
|
|
!media recent [movies|tv]
|
|
!media watched
|
|
!media find <query>
|
|
!media resume
|
|
!media random [movie|tv]
|
|
|
|
# Sonarr / Radarr / Lidarr
|
|
!media queue
|
|
!media upcoming
|
|
!media missing
|
|
!media music <q>
|
|
!media music add <q|N>
|
|
!media health
|
|
|
|
# Downloads (NZBGet + qBittorrent)
|
|
!media activity
|
|
!media completed
|
|
!media speed
|
|
!media pause / unpause
|
|
|
|
# Subscriptions / digest
|
|
!media subscribe <show>
|
|
!media unsubscribe <show>
|
|
!media subscriptions
|
|
!media digest # fire today's digest now
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- maubot **0.3.1+** running somewhere reachable from your Matrix server.
|
|
- A Matrix user for the bot. Provision via `/_synapse/admin/v1/register` (Synapse) or your homeserver's equivalent, then log in once to capture an `access_token` + `device_id` for the maubot client config.
|
|
- At minimum: Sonarr **and** Radarr (or just one, with the other left as the placeholder URL — the missing one will fail searches for that media type).
|
|
- Optional: Seerr/Jellyseerr/Overseerr, Emby, NZBGet, qBittorrent, Lidarr.
|
|
|
|
## Build & install
|
|
|
|
```bash
|
|
git clone https://git.3ddbrewery.com/maddox/maubot-media.git
|
|
cd maubot-media
|
|
|
|
# Bump the plugin id in maubot.yaml if you fork this — it must be unique per
|
|
# maubot instance. The current id (com.3ddbrewery.media) is reserved for the
|
|
# upstream deployment.
|
|
|
|
PLUGIN_VERSION=$(grep '^version:' maubot.yaml | awk '{print $2}')
|
|
zip -rq "com.3ddbrewery.media-v${PLUGIN_VERSION}.mbp" \
|
|
maubot.yaml base-config.yaml media_bot/ README.md LICENSE \
|
|
-x '*/__pycache__/*'
|
|
```
|
|
|
|
Upload `*.mbp` via the maubot UI's *Plugins → upload*, then create an instance pointing at your bot user.
|
|
|
|
## Configuration
|
|
|
|
All config lives in the maubot UI's *instance config* tab; the defaults shipped in `base-config.yaml` use placeholder hostnames (`http://sonarr:8989`, etc.) and `CHANGEME` API keys.
|
|
|
|
### Required
|
|
|
|
```yaml
|
|
sonarr:
|
|
url: http://<sonarr-host>:8989
|
|
api_key: <sonarr-api-key>
|
|
|
|
radarr:
|
|
url: http://<radarr-host>:7878
|
|
api_key: <radarr-api-key>
|
|
|
|
user_map:
|
|
"@alice:example.com":
|
|
seerr_user_id: 1 # only required if Seerr is configured
|
|
emby_user_id: "abc123def" # only required for Emby commands
|
|
```
|
|
|
|
### Seerr (optional)
|
|
|
|
If `seerr.url` and `seerr.api_key` are set, search/request route through Seerr (with its approval workflow + 👍/👎 admin reactions). If left empty, the bot falls back to direct Sonarr/Radarr lookup + add — no approval, no per-user request quotas, but no Seerr install needed either.
|
|
|
|
```yaml
|
|
seerr:
|
|
url: http://<seerr-host>:5055
|
|
api_key: <seerr-api-key>
|
|
```
|
|
|
|
### Lidarr / Emby / Downloads
|
|
|
|
All optional — the corresponding commands fail gracefully when the service isn't reachable. Commands that need them: Lidarr (`!media music`), Emby (`!media nowplaying|recent|watched|find|resume|random`), NZBGet/qBt (`!media activity|completed|speed|pause|unpause` and the daily digest's "completed" section).
|
|
|
|
### Webhooks (optional)
|
|
|
|
Two endpoints are exposed when the plugin's `webapp` is enabled (default):
|
|
|
|
| URL | Purpose |
|
|
|---|---|
|
|
| `/_matrix/maubot/plugin/<instance>/seerr-webhook` | Seerr → Matrix notifications (request created/approved/available/etc) |
|
|
| `/_matrix/maubot/plugin/<instance>/sonarr-webhook` | Sonarr Download events → ping subscribers |
|
|
|
|
Configure them in Seerr/Sonarr's *Settings → Notifications/Connect → Webhook* and set `Authorization: Bearer <secret>` headers. The shared secret is `seerr_webhook_secret` / `sonarr_webhook_secret` in the instance config; leave empty to disable auth (not recommended).
|
|
|
|
### Notifications room + digest
|
|
|
|
```yaml
|
|
notifications_room: "!roomid:example.com" # bot must be joined
|
|
digest_enabled: true
|
|
digest_hour: 8 # local hour, 24h
|
|
```
|
|
|
|
The Sunday digest can also pull a recap from an ntfy topic (e.g. an external library-cleaner job that posts its summary). Set `ntfy_url` to enable.
|
|
|
|
## Notes for forkers
|
|
|
|
- The plugin id (`com.3ddbrewery.media`) is unique per maubot deployment — change it in `maubot.yaml` before building if you're running this alongside the upstream instance.
|
|
- No personal data is stored *in* the plugin: every URL, key, and Matrix-ID lives in the instance config you set in the maubot UI.
|
|
- The plugin's SQLite tables (`subscriptions`, `digest_state`) are managed via maubot's `UpgradeTable`; nothing manual needed.
|
|
|
|
## License
|
|
|
|
MIT — see `LICENSE`.
|