Skip to content

feat(notifications): support multiple Discord IDs separated by comma/semicolon#2712

Open
defaultdino wants to merge 8 commits intoseerr-team:developfrom
defaultdino:feat(discord-agent)/multiple-discord-ids
Open

feat(notifications): support multiple Discord IDs separated by comma/semicolon#2712
defaultdino wants to merge 8 commits intoseerr-team:developfrom
defaultdino:feat(discord-agent)/multiple-discord-ids

Conversation

@defaultdino
Copy link
Copy Markdown

@defaultdino defaultdino commented Mar 17, 2026

feat #1130

Description

How Has This Been Tested?

  1. Create discord webhook on discord server
  2. Enable discord notification agent in seerr with aforementioned webhook
  3. Add both my user id and alt account user id in profile/settings/notifications/discord section (separate by commas or semicolons)
  4. send test notification, also trigger notification type rule (Request Automatically Approved)

Screenshots / Logs (if applicable)

discord_notification image

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • New Features

    • Discord ID settings accept multiple IDs per user (comma/semicolon-separated); admins can have multiple IDs too.
    • UI controls added to add/remove multiple Discord IDs.
  • User-facing

    • Validation and guidance updated to explain multi-ID input and surface errors for invalid IDs.
    • Webhook mentions are limited to the computed user IDs and an optional webhook role ID.
  • Documentation

    • Notification docs and translations updated to reflect multi-ID support.

@defaultdino defaultdino requested a review from a team as a code owner March 17, 2026 12:18
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds 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 allowed_mentions with parsed user and optional role IDs.

Changes

Cohort / File(s) Summary
Backend Discord Notification Handler
server/lib/notifications/agents/discord.ts
Parse discordId as comma/semicolon-separated list, trim/filter entries, validate snowflake format (17–20 digits), expand into multiple <@id> mentions for user and admin notifications, and build allowed_mentions containing computed user IDs and optional role ID.
Frontend Discord ID Inputs & Validation
src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx, src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
Change single discordId string to discordIds array handling: split on commas/semicolons, trim/filter, add/remove UI controls, update Formik model and Yup schema to validate each entry as a Discord snowflake, and submit joined comma string as persisted value.
Localization Strings
src/i18n/locale/en.json
Update Discord-related i18n strings to reference multiple IDs and instruct separating values with commas or semicolons; adjust labels and tips to plural form.
Documentation
docs/using-seerr/notifications/webhook.md
Clarify that Discord ID template variables may contain multiple comma/semicolon-separated values and adjust table wording/formatting for notify/request/issue/comment variables.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled commas and semicolons bright,

Household hops now ping through the night,
Trims and flatMaps make each mention sing,
Many IDs, one soft rabbit spring 🎉

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: supporting multiple Discord IDs separated by comma/semicolon, which aligns with the primary change across all modified files.
Linked Issues check ✅ Passed The PR fully addresses issue #1130 by implementing support for multiple Discord IDs separated by commas/semicolons in both the backend Discord agent and frontend UI components, enabling household accounts to map multiple Discord users to a single Jellyseerr account.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing multiple Discord ID support: validation updates, form handling, backend Discord mention parsing, and documentation/translation updates. No unrelated modifications detected.

✏️ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7920970 and 9cc4cf0.

📒 Files selected for processing (4)
  • server/lib/notifications/agents/discord.ts
  • src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
  • src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
  • src/i18n/locale/en.json

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 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_username as "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

📥 Commits

Reviewing files that changed from the base of the PR and between 9cc4cf0 and 055c878.

📒 Files selected for processing (1)
  • docs/using-seerr/notifications/webhook.md

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 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 content will 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

📥 Commits

Reviewing files that changed from the base of the PR and between 055c878 and eb50f4b.

📒 Files selected for processing (2)
  • server/lib/notifications/agents/discord.ts
  • src/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

Copy link
Copy Markdown
Member

@gauthier-th gauthier-th left a comment

Choose a reason for hiding this comment

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

For the Discord ID input, I'd prefer a list of inputs like what we did for the webhook headers (but with only one item per line), instead of single input with commas for the separation:
Image

@defaultdino
Copy link
Copy Markdown
Author

defaultdino commented Mar 23, 2026

@gauthier-th That makes more sense, I'll see what I can do about that

@defaultdino
Copy link
Copy Markdown
Author

This is now how it looks

discord-multiuser-ids

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between eb50f4b and b71f42d.

📒 Files selected for processing (3)
  • docs/using-seerr/notifications/webhook.md
  • src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
  • src/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

@defaultdino defaultdino requested a review from gauthier-th March 23, 2026 18:44
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.

feature: Assign multiple Discord user ID's to a single user in Jellyseerr

3 participants