Skip to content

feat: Automatically tag Audiobookshelf items with req:<username> per requester - #232

Open
NichCodes wants to merge 1 commit into
kikootwo:mainfrom
NichCodes:feature/requester-tags
Open

feat: Automatically tag Audiobookshelf items with req:<username> per requester#232
NichCodes wants to merge 1 commit into
kikootwo:mainfrom
NichCodes:feature/requester-tags

Conversation

@NichCodes

Copy link
Copy Markdown

Tag Audiobookshelf items with req:<username> per requester

Closes #229

Summary

Adds an optional Audiobookshelf-only feature that writes a req:<sanitized_username> tag onto each ABS library item when RMAB matches a completed download to a request. Because every request method (Web UI, API, and eventually Discord) produces a Request with an associated user, tagging happens at match time so all methods are covered by one path. ABS supports per-user library filtering by tag, so admins can scope what each user sees by their req:<username> tag.

The end result is that RMAB will allow Audiobookshelf admins to easily give each user a private library by simply allowing them to see only the requests tagged with their own username (or any number of others).

New RMAB Checkbox Example ABS User Tag Filter

How it works

  • Setting: audiobookshelf.tag_requester (default off) — new checkbox in Settings → Library → Audiobookshelf.
  • Tag format: req: + username lowercased, trimmed, spaces→_, characters outside [a-z0-9_-] stripped (John Smithreq:john_smith). Usernames that sanitize to nothing (all-symbol or non-Latin) are skipped rather than collapsed onto a shared bare req: tag.
  • Merge, never overwrite: GET the item's media.tags, union with the new tag (dedupe), PATCH /items/:id/media back — so manual tags (e.g. nsfw) and other requesters' tags are preserved. Writes are skipped when nothing changes.
  • Applied at both match paths: scan-plex.processor.ts (full scan) and plex-recently-added.processor.ts (scheduled recently-added check) — a request matched by either is excluded from the other, so both must tag.
  • Backfill: toggling the setting false→true enqueues a one-time backfill_requester_tags job that tags already-available audiobook requests.
  • Best-effort: tagging never throws; failures are logged and the scan/backfill continues.

Changes

  • src/lib/services/audiobookshelf/api.tsPATCH method, formatRequesterTag() (returns '' for unusable usernames), addABSItemTags() (merge + drops empty tags).
  • src/lib/processors/scan-plex.processor.ts, src/lib/processors/plex-recently-added.processor.ts — tag at match time, skipping empty tags.
  • src/lib/processors/backfill-requester-tags.processor.ts — one-time backfill (new).
  • src/lib/services/job-queue.service.tsbackfill_requester_tags job type, enqueue method, processor registration.
  • src/app/api/admin/settings/route.ts (GET expose) + src/app/api/admin/settings/audiobookshelf/route.ts (save key + false→true backfill trigger).
  • src/app/admin/settings/lib/types.ts + .../LibraryTab/AudiobookshelfSection.tsxtagRequester setting + checkbox.
  • Docs: documentation/features/requester-tags.md (new), settings-pages.md, TABLEOFCONTENTS.md.

Scope / non-goals

  • Plex backend: out of scope — ABS-only; the setting lives in the ABS section.
  • Tag removal on delete: not needed — cascading /delete removes the whole ABS item.
  • Idempotent: merge dedupes; available requests are excluded from the match loops, so no repeat API calls outside the one-time backfill.
  • Empty/unknown usernames are skipped.

Testing

  • Unit tests: ABS client (formatRequesterTag incl. empty-sanitize cases, merge / skip-no-op / empty-tag / error), match-time tagging on both the scan and recently-added paths, the backfill processor (query filter + tag/skip counts), and the false→true backfill enqueue.
  • dockerfile.unified builds clean; full npm run test green except for pre-existing unrelated frontend page-test failures (tracked/fixed on feature/discord-request-tags).
  • Verified live against a real ABS server: backfill + match-time tagging both produce req:<username> while preserving existing genre tags.

@NichCodes NichCodes changed the title feat: # Tag Audiobookshelf items with req:<username> per requester feat: Automatically tag Audiobookshelf items with req:<username> per requester Jun 19, 2026
…ster

Optionally writes a req:<sanitized_username> tag onto each ABS item when a
completed download is matched to a request, so admins can scope per-user
library access by tag. Tagging happens at match time (both the full scan and
the recently-added check), tags are merged (never overwritten), and toggling
the setting on backfills already-available requests via a one-time job.

Usernames that sanitize to nothing are skipped rather than collapsing onto a
shared bare req: tag. ABS-only; Plex backend is out of scope.

Closes kikootwo#229
@NichCodes
NichCodes force-pushed the feature/requester-tags branch from 0267017 to 8b03dbf Compare June 19, 2026 07:07
@Bishop-trevorstuart

Copy link
Copy Markdown

This is similar to the first script in my PR #96 (comment) Although this one is better IMO. Only thing I'd want to "adjust" is make it able to apply this tag even if Plex is the backend. I'm still using Plex as backend JUST for user management, but actual organization/consumption of audiobooks all via ABS.

@NichCodes

Copy link
Copy Markdown
Author

I've never used ABS with Plex, so I decided not to touch it just in case I broke something I couldn't test properly. I could try to implement it, but I'd need someone else who does use it with Plex to test it out before merging.

@Bishop-trevorstuart

Copy link
Copy Markdown

I'd be more than willing to do testing of this. I THINK it would have little to no impact, but understand wanting to test it of course! Currently I have RMAB configured to Auto-Tag audiofiles with Metadata; coerse file format for plex compatability and auto-merge chapters to M4B. As I mentioned I never actually consume the audiobooks via plex only ABS. The only real issue I can think of is when I trigger ABS to match the book and get the metadata for itself it's going to over-write any tags pushed from RMAB (at least I think it will). And I'm not totally sure how to best handle that. I think I'd need RMAB to handle the metadata 100% (which with my existing settings is almost does). Someday I'll likely "upgrade" to use ABS as my backend so I get all the correct feature set. I'm just sticking with Plex for the "easy" user management that provides.

@NichCodes

Copy link
Copy Markdown
Author

I'll wait until @kikootwo reviews the standing PRs before I take a stab at it. I'll tag you in the draft to test it once it's ready to test.

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.

[Request] Add post-import requester tagging support for easier ABS library management

2 participants