feat: add On Grab notification event#162
Open
xFlawless11x wants to merge 1 commit intokikootwo:mainfrom
Open
Conversation
This was referenced Mar 25, 2026
Adds request_grabbed event that fires when a torrent/NZB is successfully handed off to the configured download client, filling the gap between request_approved (pre-search) and request_available (fully imported). - Add request_grabbed to NOTIFICATION_EVENTS with titleByRequestType (Audiobook Grabbed / Ebook Grabbed), info severity, Details messageLabel - Add NotificationEventConfig interface and update getEventMeta() return type to expose messageLabel to all providers without TypeScript errors - Add messageLabel: 'Reason' to issue_reported event - Fix all 4 providers (Discord, ntfy, Pushover, Apprise) to derive message field label from meta.messageLabel ?? 'Error' instead of hardcoded isIssue ternary — prevents grab details showing as Error - Trigger request_grabbed in download-torrent.processor.ts after client.addDownload() succeeds; message carries torrent title, indexer, and download client name; requestType sourced from request.type - Update notifications.md documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3d769f3 to
ba1efa8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new
request_grabbednotification event that fires when a torrent or NZB is successfully handed off to the configured download client; the RMAB equivalent of Sonarr/Radarr's "On Grab" notification. Previously, no notification fired at the actual grab moment. Addresses #161Background & Motivation
RMAB already had five notification events:
request_pending_approvalrequest_approvedrequest_availablerequest_errorissue_reportedThe gap:
request_approvedis not the same as "on grab." A request can be approved while still waiting for a search result (statusawaiting_searchorpending). The actual grab — the moment the torrent/NZB file is sent to the configured download client — happened silently with no notification.This PR adds
request_grabbed, which fires from insidedownload-torrent.processor.tsimmediately afterclient.addDownload()succeeds and theDownloadHistoryrecord is created. At that point the download client has definitively accepted the file.Changes
1.
src/lib/constants/notification-events.tsrequest_grabbedtoNOTIFICATION_EVENTSwith:titleByRequestType: resolves to "Audiobook Grabbed" or "Ebook Grabbed" depending on request typeseverity: 'info',priority: 'normal'messageLabel: 'Details'(see item 2 below)messageLabel: 'Reason'to the existingissue_reportedevent (see item 2)NotificationEventConfiginterface — a normalized, provider-facing type that broadens theas constliteral union and explicitly declaresmessageLabel?: stringas an optional fieldgetEventMeta()return type from the raw inferred union toNotificationEventConfig, resolving TypeScript errors in all providers that accessmessageLabel2.
src/lib/services/notification/providers/— all 4 providersRoot cause fixed: All four providers (Discord, ntfy, Pushover, Apprise) had hardcoded logic for labeling the
messagepayload field:This meant any future event that used the⚠️ Error:" label, which isn't exactly accurate.
messagefield for non-error context — includingrequest_grabbed— would have its content displayed under an "Fix applied consistently across all providers:
The label and emoji now derive from event metadata:
request_error→ nomessageLabel→ defaults to⚠️ Error:issue_reported→messageLabel: 'Reason'→ renders as📝 Reason:request_grabbed→messageLabel: 'Details'→ renders as📝 Details:Per-provider changes:
discord.provider.ts): embed field name changed fromisIssue ? 'Reason' : 'Error'tometa.messageLabel ?? 'Error'ntfy.provider.ts): addedconst meta = getEventMeta(event)insideformatMessage; replaced hardcoded label withmeta.messageLabel ?? 'Error'+ severity-driven emojipushover.provider.ts):metawas already in scope; replaced hardcoded label withmeta.messageLabel ?? 'Error'+ severity-driven emojiapprise.provider.ts): addedconst meta = getEventMeta(event)insideformatMessage; replaced hardcoded label withmeta.messageLabel ?? 'Error'+ severity-driven emoji3.
src/lib/processors/download-torrent.processor.tsAdded grab notification trigger after the
DownloadHistoryrecord is created (i.e., afterclient.addDownload()has confirmed success):request.user.plexUsernamefor the notification (same DB-lookup pattern used inmonitor-download.processor.ts)request_grabbedviajobQueue.addNotificationJob()messagefield carries:"<torrent title> via <indexer> (<clientType>)"— gives recipients full context on what was grabbed and from whererequestTypeis read fromrequest.type(the actual DB value) rather than inferred from protocol, ensuring correct title resolution for ebooks vs audiobooks4.
documentation/backend/services/notifications.mdrequest_grabbedrequest_grabbedtitleByRequestTypeexamples to the Dynamic Titles sectionWhat the Grab Notification Looks Like
For a grab of an audiobook torrent, the notification payload resolves to:
This follows the same structure as all other RMAB notifications — book title, author, requesting user, and an optional labeled message field. The
messagefield here carries torrent/indexer details the same wayrequest_errorcarries error text andissue_reportedcarries the user's reason.Provider Compatibility
request_grabbedis included inNOTIFICATION_EVENTSand will appear as a subscribable checkbox in the notification backend settings UI for all four providers automatically — no UI changes required. The event is delivered through the same async Bull job queue as all other events.Tested on my UnRaid instance, screenshots here:
AI Disclosure
Claude Sonnet 4.6 was used to develop this PR, I did not see any specific no AI use language for this project but apologies if I overlooked something!