Skip to content

feat(providers): add Seerr integration (Overseerr/Jellyseerr compatible) - #59

Merged
itz4blitz merged 4 commits into
itz4blitz:masterfrom
vbrzezina:feat/seerr-integration
Oct 16, 2026
Merged

itz4blitz merged 4 commits into
itz4blitz:masterfrom
vbrzezina:feat/seerr-integration

Conversation

@vbrzezina

@vbrzezina vbrzezina commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a Seerr integration (@logarr/provider-seerr). Seerr is the merged successor of Overseerr and Jellyseerr. All three expose the same /api/v1, so one provider covers them.

What it ingests

  • Activity: media requests and issues.
    • There is one activity row per status transition, with ids like seerr-request-<id>-status-<n> and seerr-issue-<id>-status-<n>.
    • Results are sorted by modified and filtered against the last sync time, reading at most 3 pages of 50. If that cap is reached, a warning is logged.
    • User emails and issue comment text are deliberately left out of the activity text, because it ends up in the UI and in the AI analysis context.
  • Log files: tails seerr-YYYY-MM-DD.log, plus the legacy overseerr-*.log and jellyseerr-*.log.
    • The seerr.log symlink and the .machinelogs*.json files are excluded.
    • The parser handles the winston format ts [level][Label]: message {json}, including the optional label, trailing JSON metadata, ANSI codes and stack traces.
    • Metadata detection is capped, so adversarial lines can't trigger quadratic parsing (covered by timing tests).
  • Connection test: calls /settings/about, which checks the admin API key and returns the version.

Wiring

  • Backend:
    • provider registration in IngestionService and ServersService;
    • env seeding with SEERR_URL, SEERR_API_KEY and SEERR_LOGS_PATH, mounted at /seerr-logs;
    • proxy path /api/v1, both Dockerfiles, the compose files and turbo.json env.
  • Frontend:
    • One available Seerr integration replaces the overseerr and jellyseerr coming-soon entries.
    • Provider icon from dashboard-icons.
    • "Open in app" link from the logs page.
  • README updates.

Notes

  • Removed entries: the separate overseerr and jellyseerr coming-soon entries in integrations.ts are replaced by the single seerr entry. Searching for either name still finds it.
  • Error handling: follows the same rules as the other providers. Each source fails on its own with a [seerr] Failed to get … log line, the poll fails only when every source fails, and calls before connect throw Not connected.
  • issue_source has no seerr value, so issues fall back to system. That is the same as Plex, Emby and Whisparr today, and is out of scope here.
  • Request titles would need TMDB lookups, so they show as tmdb:<id> to avoid extra API calls.

Testing

  • @logarr/provider-seerr has 122 unit tests covering:
    • the parser, including realistic samples, edge cases and adversarial-input timing tests;
    • the client: paging, envelope variants and error handling;
    • the provider: status ids, since filtering, paging caps, partial failure and privacy rules.
  • Realistic multi-line Seerr logs go through the real LogFileProcessor end to end.
  • pnpm build, pnpm lint, pnpm typecheck and pnpm test all pass. pnpm install --frozen-lockfile is clean, and the lockfile diff only adds the new package.
  • Request and issue status enums were checked against seerr-team/seerr source.
  • Not yet tested against a live Seerr instance.

pnpm format:check already fails on master (pre-existing files); the files added or changed here are prettier-clean.

@vbrzezina

Copy link
Copy Markdown
Contributor Author

Part of a set of integration PRs. Overview, merge order and design notes: #64

@vbrzezina
vbrzezina marked this pull request as ready for review October 12, 2026 16:43

@itz4blitz itz4blitz left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Seerr provider looks correct and I would merge it on its own. The client uses /api/v1 and X-Api-Key, list calls match the request and issue routes, secrets are not copied into activity metadata, and the winston line parser matches seerr-YYYY-MM-DD.log while skipping the seerr.log symlink and .gz archives. The metadata split is bounded (16 attempts, 64KB tail).

I am not merging it in this pass. It conflicts with the other integration PRs on the shared wiring (ingestion.service.ts, servers.service.ts, Dockerfiles, compose, env files, integrations.ts, turbo.json). #57 and #60 are going in first. Please rebase onto current master after those land. No code changes requested.

Non-blocking:

  • The 3-page cap comment cites the /settings/logs rate limit. This provider never calls that route. The cap itself is fine; the rationale is not.
  • userName() prefers displayName, which Seerr sets to the email when there is no username. Prefer the username fields, and do not surface an email as the display name.
  • The section banners restate the methods under them.

Add @logarr/provider-seerr for Seerr, the merged successor of Overseerr and
Jellyseerr (same /api/v1, so all three are supported by one provider).

- X-Api-Key client; connection test and version via /settings/about
- Activity from media requests and issues, one row per status transition
  (seerr-request-<id>-status-<n>), with since-filtering and bounded paging
- File tailing of seerr-*.log / overseerr-*.log / jellyseerr-*.log with a
  winston line parser that handles labels, JSON metadata and stack traces
- Backend registration, env seeding (SEERR_URL/SEERR_API_KEY, /seerr-logs),
  proxy path, Dockerfiles, compose, turbo env
- Frontend: single available "Seerr" integration replaces the Overseerr and
  Jellyseerr coming-soon entries; provider icon and logs deep link
- README updates
@vbrzezina
vbrzezina force-pushed the feat/seerr-integration branch from e7ab024 to 99b7cab Compare October 13, 2026 13:07
@vbrzezina

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I rebased onto master now that #57 and #60 are in. The conflicts in the shared wiring were purely additive, so Lidarr and Seerr now sit side by side. The lockfile diff against master adds only the new package.

The three non-blocking items are done as well:

  • Page-cap comment: it now gives the actual reason, bounding API calls and data per poll after a long outage, and no longer mentions /settings/logs.
  • userName(): it prefers username, then plexUsername, then jellyfinUsername, and only then displayName. It never shows a value containing @, and falls back to user <id>. Tests added.
  • Section banners: removed.

I also commented out the Seerr variables in .env.tpl, with a note, because the vault items don't exist yet; this follows your op inject point on #58. Build, lint, typecheck and tests pass.

@itz4blitz
itz4blitz merged commit f7b4498 into itz4blitz:master Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants