VaultRequestrr

VaultRequestrr

Docker app from vancityactivist's Repository

Overview

A Discord bot that requests movies and TV shows through Seerr (the Overseerr/Jellyseerr successor). The first time a user requests something, the bot asks for their Plex username/email and links their Discord account to their Seerr user, so every request is attributed to them and their per-user quotas/limits are respected. The link is stored locally (SQLite) and written back into Seerr notification settings. Features: /movie and /tv search with availability indicators and season selection; /quota shows remaining limits and reset time; DM notifications when a request becomes available or is declined; and an optional password-protected admin dashboard (set a Dashboard Password to enable it on port 5056) for managing links, viewing activity, and toggling settings.

VaultRequestrr

CI Docker License: MIT Python 3.12 GHCR Buy Me a Coffee

A Discord bot for requesting movies and TV shows through Seerr (the unified successor to Overseerr/Jellyseerr), with self-service Plex account linking so that each user's requests are attributed to their Seerr account and their per-user quotas/limits are respected.

Why this exists

Tools like requestrr attribute a request to the right Seerr user by matching a Discord ID that an admin has to hand-enter into each Seerr user's notification settings. After the Overseerr → Seerr migration those IDs are typically empty, so every request falls through to a single default user (or fails) and per-user quotas stop working.

VaultRequestrr fixes this without any admin busywork: the first time a user requests something, the bot asks for their Plex username/email, resolves it to a Seerr user, remembers the link, and from then on submits every request as that user. The link is also written back into Seerr's notification settings so it's visible in the Seerr UI.

How it works

  1. A user runs /movie <title> or /tv <title>.
  2. The bot searches Seerr and shows the results to pick from (TV adds a season picker).
  3. On the user's first request, a popup asks for their Plex username/email.
    • It must match an existing Seerr user (log into Seerr once if not yet imported from Plex).
  4. The link is saved (SQLite) and written back to Seerr.
  5. The request is submitted with that user's userId, so Seerr applies their quota/permissions.

Search results and the season picker show availability at a glance (✅ available, 🟡 partial, ⏳ processing, 🕒 requested), and the Request button greys out when the selected media/seasons are already present. Results beyond 25 paginate.

Reporting issues

Users run /issue <title> to report a problem (Video / Audio / Subtitle / Other) with media already on the server. The bot searches movies and TV, limits results to in-library titles, applies the same link gate as requests, then collects a short description and files it to Seerr's issue tracker. For TV the form also asks which season and episode is affected, so issues are pinned to a single episode. Because Seerr's API attributes every API-key issue to the admin account, the real reporter is recorded in the issue message and tracked locally so the dashboard and resolution DMs know who filed it.

When an issue is filed, VaultRequestrr DMs the configured issue handlers (and posts to an optional issue channel) with a card carrying Re-grab and Resolve buttons — persistent, like the request buttons. Re-grab sets the title monitored, runs an interactive search and grabs a replacement (only deleting the existing file once a release is found), resolving the issue only if a release is actually grabbed; Resolve just marks it resolved. The same actions live on the dashboard Issues page. Re-grab is the fix for a bad/corrupt file: Radarr/Sonarr won't grab for an unmonitored item, so it ensures monitoring first.

Who gets issue notifications (and can act on them) and which channel they post to are set on the dashboard Settings → Approvals & Issues → Issue notifications card — leave either field blank to reuse the request approvers / approvals channel.

Approving requests

Seerr only auto-fulfils requests for users with the auto-approve permission; everyone else's land pending. When a bot-submitted request comes back pending, VaultRequestrr immediately DMs every configured admin (and posts to an optional approvals channel) with Approve / Decline buttons — these are persistent, so they keep working hours later and across restarts. Admins can also run /pending to review the full queue (sourced from Seerr, so it catches requests made outside the bot) or use the dashboard Approvals page. Approving/declining calls Seerr and the requester is DM'd the outcome.

Admins are a configured list of Discord user ids — set ADMIN_DISCORD_IDS or manage them on the dashboard Settings → Approvals & Issues → Request approvals card (which also sets the approvals channel). That list gates /pending, the buttons, and who gets notified about requests.

Inviting friends to Plex

Linked users can run /invite to bring a friend onto the Plex server. The bot asks for the friend's Plex email and issues a real Plex share, so Plex emails the friend the invite — Discord only triggers it. Invites are gated three ways: an admin must connect Plex and enable invites, the inviter must have linked their own account, and each user has a configurable cap (default 3, overridable per-user on the Links page). Connect Plex from the Settings page with Login with Plex (PIN OAuth — no token to copy), then pick which server and which libraries to share. Sent invites are listed on the dashboard Invites page.

Anime requests

/anime <title> is a separate category that routes anime to dedicated Sonarr/Radarr instances — handy if you keep anime on its own library (the way Requestrr does it). It searches both series and films and sends each pick to the matching anime instance.

Configure it on the dashboard Settings → Anime routing card (or via the ANIME_SONARR_SERVER_ID / ANIME_RADARR_SERVER_ID env vars). Enter the Seerr instance id of your anime Sonarr/Radarr — the card lists the configured instances and their ids, or find them in Seerr under Settings → Services. Setting a server id is what enables /anime for that media type; with neither set, the command tells the user it isn't configured. Profile id and root folder are optional advanced overrides — leave them blank to let Seerr apply that instance's own anime quality profile / root folder.

Prerequisites & caveats: the anime Sonarr/Radarr instance must already be set up in Seerr (ideally with its Anime Quality Profile / Anime Root Folder). The bot only selects which instance a request goes to — whether a series is added as anime (absolute episode numbering) is decided by Seerr's own anime detection (a TMDB keyword), not the bot. A title Seerr doesn't recognise as anime will land as a standard series even on the anime instance; fix it by adding the TMDB "anime" keyword or correcting the series type in Sonarr.

Notifications

The bot DMs the requester when their request becomes available or is declined, and DMs the reporter when their issue is marked resolved. Only requests and issues made through the bot are tracked.

Delivery is driven by a Seerr webhook for near-instant DMs. Set a webhook secret — either the WEBHOOK_SECRET env var or, more conveniently, the Seerr webhook card on the dashboard Settings page (which also shows the exact URL to paste) — then in Seerr enable Settings → Notifications → Webhook and point it at:

http://<vaultrequestrr-host>:<WEB_PORT>/webhook/seerr?token=<WEBHOOK_SECRET>

(The default JSON payload works as-is — no template needed.) A background poller also runs and adapts to whether a webhook is configured: with no webhook it polls every 2 minutes so polling-only setups stay near-real-time, and once a webhook is set it relaxes to the POLL_INTERVAL_SECONDS backstop (default 600) since the webhook now carries delivery. Either way notifications are never lost if a webhook is missed. Set POLL_INTERVAL_SECONDS=0 to disable polling entirely.

Admin dashboard

If WEB_PASSWORD is set, a small web dashboard is served on WEB_PORT (default 5056): health (Discord/Seerr/Plex status), linked accounts (with unlink/remap and per-user invite caps), recent request activity, an Approvals page (approve/ decline pending requests), reported issues (with resolve/reopen and re-search actions), sent Plex invites, a live log viewer (level filter + auto-refresh), and a Settings page. Sign in with the password.

The Settings page lets you edit the Seerr connection (URL + API key) — the connection is validated before saving, applied immediately without a restart, and persisted to the database (the SEERR_URL / SEERR_API_KEY env vars are only the first-run default). It also exposes a Seerr webhook card (set/clear the webhook secret and copy the ready-to-paste URL), an Approvals & admins card (approver Discord ids + the optional approvals channel), the bot behaviour toggles, a Plex Invites section (Login with Plex, server + library selection, enable toggle and per-user invite cap), and a Radarr / Sonarr connections manager.

VaultRequestrr talks to Radarr/Sonarr directly with its own credentials. Add one or more instances (URL + API key, with optional 4K and default flags) on the Settings page — each is validated before saving and stored in the database. Seerr is still used to locate which instance holds a given title (it resolves the internal movie/series id), but all data reads and actions run against your configured connections. This unlocks richer media tooling:

  • Media details — from an issue's Details action, see the current file's quality/size/languages, monitored state, and live download-queue progress, read straight from the arr.
  • Re-search acts on a bad download: it deletes the current file in Radarr/Sonarr and triggers a fresh search for a replacement — for a movie, the movie file; for TV, just the reported episode's file. (Radarr/Sonarr can't "blocklist but keep the file" for an already-imported release, so removing the file is what reliably forces a new grab.)
  • Manual search — run an interactive indexer search and grab a specific release from the candidate list, instead of relying on auto-search.

Commands:

Command Description
/movie <title> Search for and request a movie
/tv <title> Search for and request a TV show (with season selection)
/anime <title> Search anime (series and films) and route it to the anime library (when configured)
/issue <title> Report a Video/Audio/Subtitle/Other problem with media on the server
/invite Invite a friend to Plex by email (linked users; admin-enabled)
/quota Show your remaining request quota and when it resets
/myrequests List your recent requests and their current status
/pending (Admin) Review, approve, and decline requests awaiting approval
/linkstatus Show which Seerr account you're linked to
/unlink Remove your link (you'll be asked again on the next request)

Setup

1. Create a Discord bot

2. Get your Seerr API key

  • Seerr → Settings → General → API Key. It must belong to an admin user (needed to look up users and submit requests on their behalf).

3. Configure

cp .env.example .env
# edit .env: DISCORD_TOKEN, SEERR_URL, SEERR_API_KEY
# set DISCORD_GUILD_ID to your server id for instant slash-command registration

4a. Run with Python

python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m vaultrequestrr

4b. Run with Docker

docker compose up -d --build

The SQLite link store is persisted to ./data.

To run the pre-built published image instead of building locally:

docker run -d --name vaultrequestrr --restart unless-stopped \
  -e DISCORD_TOKEN=... \
  -e SEERR_URL=http://10.10.0.10:5055 \
  -e SEERR_API_KEY=... \
  -e DISCORD_GUILD_ID=... \
  -v /path/to/data:/data \
  ghcr.io/vancityactivist/vaultrequestrr:latest

4c. Run on Unraid

The image is published to GHCR and there's a ready-made Unraid template at unraid/vaultrequestrr.xml.

  1. Install the template into Unraid's user-templates folder. The Add Container Template field is a dropdown — you cannot paste a URL into it, so the XML has to live in /boot/config/plugins/dockerMan/templates-user/ first. From the Unraid web terminal:
    wget -O /boot/config/plugins/dockerMan/templates-user/my-vaultrequestrr.xml \
      https://raw.githubusercontent.com/vancityactivist/vaultrequestrr/main/unraid/vaultrequestrr.xml
    
    (Or copy unraid/vaultrequestrr.xml onto the flash share at config/plugins/dockerMan/templates-user/my-vaultrequestrr.xml.) The my- prefix and this folder are what make it appear in the dropdown.
  2. On Unraid: Docker tab → Add Container → in the Template dropdown, under User templates, select VaultRequestrr.
  3. Fill in the fields the template exposes — Discord Bot Token, Seerr URL, Seerr API Key, and optionally Discord Guild ID — set the Data Directory (defaults to /mnt/user/appdata/vaultrequestrr), then Apply.

The bot makes outbound connections to Discord and Seerr. The only inbound port is the optional admin dashboard (5056), which is served only when you set a Dashboard Password in the template.

Configuration reference

Variable Required Default Description
DISCORD_TOKEN yes Discord bot token
DISCORD_GUILD_ID no Register commands to one guild (instant). Blank = global (~1h)
SEERR_URL yes http://localhost:5055 Base URL of your Seerr instance
SEERR_API_KEY yes Seerr admin API key
REQUIRE_LINKING no true Require Plex linking before the first request
DEFAULT_SEERR_USER_ID no Fallback user id when linking is disabled
DATABASE_PATH no data/vaultrequestrr.sqlite3 SQLite path for links
LOG_LEVEL no INFO DEBUG/INFO/WARNING/ERROR
POLL_INTERVAL_SECONDS no 600 Backstop poll interval; poller adapts to ~2 min with no webhook (0 disables)
NOTIFY_ON_AVAILABLE no true DM requester when media becomes available
NOTIFY_ON_DECLINED no true DM requester when a request is declined
NOTIFY_ON_ISSUE_RESOLVED no true DM reporter when their issue is resolved
WEB_PASSWORD no Set to enable the admin dashboard
WEB_PORT no 5056 Port the dashboard listens on
WEBHOOK_SECRET no Shared secret for the inbound Seerr webhook (blank = endpoint disabled)
ADMIN_DISCORD_IDS no Comma-separated Discord ids that can approve requests and get notified
APPROVALS_CHANNEL_ID no Optional channel id to also post pending requests to
ANIME_SONARR_SERVER_ID no Seerr Sonarr instance id for /anime series (blank = disabled)
ANIME_RADARR_SERVER_ID no Seerr Radarr instance id for /anime films (blank = disabled)
ANIME_SONARR_PROFILE_ID / ANIME_SONARR_ROOT_FOLDER no Optional anime Sonarr profile id / root folder override
ANIME_RADARR_PROFILE_ID / ANIME_RADARR_ROOT_FOLDER no Optional anime Radarr profile id / root folder override

Development

pip install -r requirements.txt pytest
pytest

Install VaultRequestrr on Unraid in a few clicks.

Find VaultRequestrr in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for VaultRequestrr Review the template variables and paths Click Install

Related apps

Details

Repository
ghcr.io/vancityactivist/vaultrequestrr:latest
Last Updated2026-07-03
First Seen2026-06-16

Runtime arguments

Web UI
http://[IP]:[PORT:5056]/
Network
bridge
Shell
sh
Privileged
false

Template configuration

Data DirectoryPathrw

Stores the SQLite database of Discord↔Seerr account links. Keep this on persistent storage.

Target
/data
Default
/mnt/user/appdata/vaultrequestrr
Value
/mnt/user/appdata/vaultrequestrr
Discord Bot TokenVariable

Bot token from https://discord.com/developers/applications (Bot tab).

Target
DISCORD_TOKEN
Seerr URLVariable

Base URL of your Seerr instance, including port. Use your LAN address, e.g. http://10.10.0.10:5055

Target
SEERR_URL
Default
http://192.168.1.10:5055
Value
http://192.168.1.10:5055
Seerr API KeyVariable

Seerr API key (Settings → General → API Key). Must belong to an admin user.

Target
SEERR_API_KEY
Discord Guild IDVariable

Optional: your Discord server ID. Set it so slash commands register instantly (otherwise global registration can take up to ~1 hour). Enable Developer Mode in Discord, right-click the server icon → Copy Server ID.

Target
DISCORD_GUILD_ID
Require LinkingVariable

Require users to link a Plex account before their first request (recommended: true).

Target
REQUIRE_LINKING
Default
true
Value
true
Default Seerr User IDVariable

Optional fallback Seerr user id used only when Require Linking is false.

Target
DEFAULT_SEERR_USER_ID
Log LevelVariable

DEBUG, INFO, WARNING, or ERROR.

Target
LOG_LEVEL
Default
INFO
Value
INFO
Dashboard PasswordVariable

Set a password to enable the admin web dashboard (view/manage links, activity, settings). Leave blank to disable the dashboard.

Target
WEB_PASSWORD
Dashboard PortPorttcp

Host port for the admin dashboard. Only used when a Dashboard Password is set.

Target
5056
Default
5056
Value
5056
Notify When AvailableVariable

DM the requester when their movie/season becomes available.

Target
NOTIFY_ON_AVAILABLE
Default
true
Value
true
Notify When DeclinedVariable

DM the requester when an admin declines their request.

Target
NOTIFY_ON_DECLINED
Default
true
Value
true
Notify When Issue ResolvedVariable

DM the reporter when their reported issue is marked resolved.

Target
NOTIFY_ON_ISSUE_RESOLVED
Default
true
Value
true
Poll Interval (seconds)Variable

How often to poll Seerr for request status changes (0 disables notifications).

Target
POLL_INTERVAL_SECONDS
Default
120
Value
120