feat(notifications): support multiple Discord IDs separated by comma/semicolon#2712
feat(notifications): support multiple Discord IDs separated by comma/semicolon#2712defaultdino wants to merge 8 commits intoseerr-team:developfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds support for multiple Discord IDs per user (comma/semicolon-separated). Frontend accepts/manages multiple IDs and validates each; backend expands stored IDs into individual Discord mentions for user/admin notifications and sets webhook Changes
Sequence Diagram(s)sequenceDiagram
participant U as User (Browser)
participant FE as Frontend
participant BE as Server (Notifications)
participant D as Discord (Webhook)
U->>FE: Enter comma/semicolon-separated Discord IDs
FE->>FE: Split, trim, validate each ID (/^\d{17,20}$/)
FE->>BE: Save settings / trigger notification (joined IDs)
BE->>BE: Split/trim/filter, flatMap to `<@id>` mentions
BE->>BE: Build allowed_mentions (user IDs, optional role ID)
BE->>D: POST webhook with content and allowed_mentions
D-->>BE: Respond (success/failure)
BE-->>FE: Ack/status
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx (1)
52-63: Consider extracting shared Discord ID validation logic.The multi-ID validation logic (split, trim, filter, regex test) is duplicated here and in
UserGeneralSettings/index.tsx. Consider extracting to a shared utility:♻️ Suggested refactor
Create a utility function in a shared location:
// e.g., in src/utils/validation.ts export const isValidDiscordIds = (value: string | null | undefined): boolean => { if (!value) return true; const ids = value .split(/[,;]/) .map((id) => id.trim()) .filter((id) => id); return ids.length > 0 && ids.every((id) => /^\d{17,19}$/.test(id)); };Then use in both components:
-.test( - 'valid-discord-ids', - intl.formatMessage(messages.validationDiscordId), - (value) => { - if (!value) return true; - const ids = value - .split(/[,;]/) - .map((id) => id.trim()) - .filter((id) => id); - return ids.length > 0 && ids.every((id) => /^\d{17,19}$/.test(id)); - } -) +.test( + 'valid-discord-ids', + intl.formatMessage(messages.validationDiscordId), + isValidDiscordIds +)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx` around lines 52 - 63, Extract the duplicated Discord multi-ID validation into a shared utility named isValidDiscordIds(value: string | null | undefined): boolean that implements the existing split(/[,;]/).map.trim().filter logic and /^\d{17,19}$/ check and returns true for empty input; then import and use isValidDiscordIds inside the validation .test callback in UserNotificationsDiscord (and replace the similar logic in UserGeneralSettings/index.tsx) so the .test simply calls isValidDiscordIds(value).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@server/lib/notifications/agents/discord.ts`:
- Around line 274-278: Update the webhook documentation and release notes to
reflect that the template variables notifyuser_settings_discordId,
requestedBy_settings_discordId, reportedBy_settings_discordId, and
commentedBy_settings_discordId now contain comma/semicolon-separated Discord IDs
(e.g., "id1,id2" or "id1;id2") instead of a single ID; explicitly document
downstream parsing expectations and note this as a potential breaking change for
consumers who treat discordId as a single value. In the docs for the Discord
webhook agent (and any webhook template reference), add guidance and examples
showing how to split/trim these values or how to mention multiple users (using
<@id>), and in the release notes call out the change and suggest migration
options such as parsing into an array or using new convenience variables
(propose adding discordId_first for primary ID and discordIds for an array) so
developers can update consumers accordingly.
---
Nitpick comments:
In
`@src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx`:
- Around line 52-63: Extract the duplicated Discord multi-ID validation into a
shared utility named isValidDiscordIds(value: string | null | undefined):
boolean that implements the existing split(/[,;]/).map.trim().filter logic and
/^\d{17,19}$/ check and returns true for empty input; then import and use
isValidDiscordIds inside the validation .test callback in
UserNotificationsDiscord (and replace the similar logic in
UserGeneralSettings/index.tsx) so the .test simply calls
isValidDiscordIds(value).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 217e3fea-e272-402b-8e69-0b65c6bd0b58
📒 Files selected for processing (4)
server/lib/notifications/agents/discord.tssrc/components/UserProfile/UserSettings/UserGeneralSettings/index.tsxsrc/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsxsrc/i18n/locale/en.json
There was a problem hiding this comment.
🧹 Nitpick comments (1)
docs/using-seerr/notifications/webhook.md (1)
129-136: Issue section Discord ID documentation is correctly updated.The Discord ID field description is properly updated to reflect multi-ID support. However, note that line 132 describes the
reportedBy_usernameas "The requesting user's username" when it should be "The reporting user's username" for clarity. This appears to be a pre-existing issue not introduced by this PR.📝 Optional terminology improvement for pre-existing text
-| `{{reportedBy_username}}` | The requesting user's username | +| `{{reportedBy_username}}` | The reporting user's username |The same clarification could apply to lines 133-134 for consistency with the
reportedBy_prefix.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/using-seerr/notifications/webhook.md` around lines 129 - 136, Update the wording for the reportedBy_* variables to replace "requesting" with "reporting" for clarity: change the descriptions for `{{reportedBy_username}}`, `{{reportedBy_email}}`, and `{{reportedBy_avatar}}` from "The requesting user's ..." to "The reporting user's ..."; also apply the same terminology change to `{{reportedBy_settings_discordId}}` and `{{reportedBy_settings_telegramChatId}}` so all `reportedBy_` entries consistently use "reporting" rather than "requesting".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/using-seerr/notifications/webhook.md`:
- Around line 129-136: Update the wording for the reportedBy_* variables to
replace "requesting" with "reporting" for clarity: change the descriptions for
`{{reportedBy_username}}`, `{{reportedBy_email}}`, and `{{reportedBy_avatar}}`
from "The requesting user's ..." to "The reporting user's ..."; also apply the
same terminology change to `{{reportedBy_settings_discordId}}` and
`{{reportedBy_settings_telegramChatId}}` so all `reportedBy_` entries
consistently use "reporting" rather than "requesting".
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0122e40f-9b97-4b5a-966d-1eb8a2e32748
📒 Files selected for processing (1)
docs/using-seerr/notifications/webhook.md
There was a problem hiding this comment.
Pull request overview
Adds support for associating multiple Discord user IDs with a single Seerr user (comma/semicolon-separated) so Discord mention notifications can reach multiple Discord accounts for “household” scenarios (fixes #1130).
Changes:
- Updated Discord User ID field validation in the profile settings UI to accept multiple IDs separated by
,or;. - Updated the Discord notification agent to expand mentions to multiple IDs for both user and admin notifications.
- Updated user-facing help text (i18n) and webhook notification documentation to reflect multi-ID behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/i18n/locale/en.json | Updates Discord ID help text to document comma/semicolon-separated multiple IDs. |
| src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx | Updates tooltip and Yup validation to accept multiple Discord IDs. |
| src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx | Updates tooltip and Yup validation to accept multiple Discord IDs in general settings. |
| server/lib/notifications/agents/discord.ts | Expands Discord mentions to multiple IDs by splitting on commas/semicolons. |
| docs/using-seerr/notifications/webhook.md | Documents that webhook template variables may now contain multiple Discord IDs. |
Comments suppressed due to low confidence (1)
src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx:70
- The validation message still refers to a single “Discord user ID” but the field now supports multiple IDs separated by commas/semicolons. Please update the message text to reflect multiple IDs to avoid misleading validation feedback.
discordId: 'Discord User ID',
discordIdTip:
'The <FindDiscordIdLink>multi-digit ID number</FindDiscordIdLink> associated with your Discord user account. Separate multiple IDs with commas or semicolons for household accounts.',
validationemailrequired: 'Email required',
validationemailformat: 'Valid email required',
validationDiscordId: 'You must provide a valid Discord user ID',
plexwatchlistsyncmovies: 'Auto-Request Movies',
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
Outdated
Show resolved
Hide resolved
…strict mentions to roles/users
There was a problem hiding this comment.
🧹 Nitpick comments (1)
server/lib/notifications/agents/discord.ts (1)
291-309: Consider deduplicating mention IDs.If the same Discord ID is configured for multiple admin users, or if a user enters the same ID multiple times, the
contentwill contain duplicate mentions (e.g.,<@123> <@123>). While Discord handles this gracefully, it may appear redundant to recipients.♻️ Optional: Deduplicate userMentions
+ const uniqueMentions = [...new Set(userMentions)]; + const allowedUserIds = userMentions.map((mention) => mention.replace(/[<@>]/g, '') ); + const uniqueAllowedUserIds = [...new Set(allowedUserIds)]; // ... later in axios.post: - content: userMentions.join(' '), + content: uniqueMentions.join(' '), allowed_mentions: { - users: allowedUserIds, + users: uniqueAllowedUserIds, roles: allowedRoleIds, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@server/lib/notifications/agents/discord.ts` around lines 291 - 309, The current logic pushes potentially duplicate mention strings into userMentions (from the userMentions array built in the block using NotificationAgentKey.DISCORD, shouldSendAdminNotification, and isValidSnowflake), so deduplicate the mentions before using them: after constructing the array (or per-user when mapping discordId entries) convert to a deduplicated collection (e.g., use a Set or filter by indexOf) so each `<@id>` appears only once; ensure you still respect the isValidSnowflake check and keep the existing checks in shouldSendAdminNotification and user.settings usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@server/lib/notifications/agents/discord.ts`:
- Around line 291-309: The current logic pushes potentially duplicate mention
strings into userMentions (from the userMentions array built in the block using
NotificationAgentKey.DISCORD, shouldSendAdminNotification, and
isValidSnowflake), so deduplicate the mentions before using them: after
constructing the array (or per-user when mapping discordId entries) convert to a
deduplicated collection (e.g., use a Set or filter by indexOf) so each `<@id>`
appears only once; ensure you still respect the isValidSnowflake check and keep
the existing checks in shouldSendAdminNotification and user.settings usage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f898712d-f57b-47dc-8c7a-9228a072f810
📒 Files selected for processing (2)
server/lib/notifications/agents/discord.tssrc/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
|
@gauthier-th That makes more sense, I'll see what I can do about that |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx`:
- Around line 52-67: The current UserNotificationsDiscordSchema defines
discordIds with .of(Yup.string().matches(DISCORD_SNOWFLAKE_REGEX,
intl.formatMessage(messages.validationDiscordId))) but the .when('types', {
then: Yup.array().min(1, ...) }) replaces that schema losing per-item
validation; change the .when to use the schema callback form so it augments the
existing array schema instead of replacing it — e.g., keep the initial
discordIds .of(...) and use .when('types', { is: (types) => !!types, then:
(schema) => schema.min(1, intl.formatMessage(messages.validationDiscordId)) })
so DISCORD_SNOWFLAKE_REGEX item validation is preserved while enforcing min when
types is truthy.
- Around line 196-200: The current check in the UserNotificationsDiscord
component only handles string errors for errors.discordIds, so per-field array
errors (e.g., [undefined, "Each ID must be..."]) never render; update the error
rendering to handle both string and array forms: if errors.discordIds is a
string, show it as before, but if Array.isArray(errors.discordIds) iterate over
that array and for each index render the individual error next to the
corresponding input only when touched.discordIds && touched.discordIds[index] is
true. Reference the existing errors.discordIds and touched.discordIds usage in
the component and perform the per-index check inside the same map that renders
the Discord ID inputs so each field displays its inline validation message.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e0ce2006-419a-4f89-9ffe-7a33b929745d
📒 Files selected for processing (3)
docs/using-seerr/notifications/webhook.mdsrc/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsxsrc/i18n/locale/en.json
✅ Files skipped from review due to trivial changes (1)
- src/i18n/locale/en.json
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/using-seerr/notifications/webhook.md


feat #1130
Description
How Has This Been Tested?
profile/settings/notifications/discordsection (separate by commas or semicolons)Screenshots / Logs (if applicable)
Checklist:
pnpm buildpnpm i18n:extractSummary by CodeRabbit
New Features
User-facing
Documentation