Skip to content

feat: add custom email template system with dynamic variables - #1883

Closed
mmenanno wants to merge 7 commits into
seerr-team:developfrom
mmenanno:feature-custom-email-templates
Closed

mmenanno wants to merge 7 commits into
seerr-team:developfrom
mmenanno:feature-custom-email-templates

Conversation

@mmenanno

@mmenanno mmenanno commented Sep 2, 2025

Copy link
Copy Markdown

Description

This PR implements a comprehensive custom email template system for Jellyseerr, enabling administrators to create personalized email notifications with dynamic variables and full customization control.

Key Features:

  • Custom Email Templates: Per-notification-type customization with subject, body, and custom HTML support
  • 17 Dynamic Variables: Including user_name, media_name, request_url, request_id, media_overview, current_date, user_request_count, days_pending, season_count, tmdb_id, imdb_id, and more
  • Template Modes: Toggle between default Jellyseerr templates and custom templates for each notification type
  • Live Preview: Real-time email preview showing actual rendered content with styling
  • Test Functionality: Send test emails for individual templates to verify configuration
  • Advanced HTML Mode: Support for fully custom HTML emails without Jellyseerr styling
  • Intuitive UI: Dedicated template management page with variables reference and bulk operations

Technical Implementation:

  • Backend: New TemplateEngine class with variable interpolation and conditional rendering ({{#is_4k}} support)
  • API Endpoints: /test-template, /preview, and /template-variables for comprehensive template management
  • Frontend: Complete template editor with save state tracking, individual/bulk saves, and error handling
  • Templates: Pug template files supporting both styled (custom-template) and raw HTML (raw-html) rendering
  • Settings Integration: Extended NotificationAgentEmail interface with granular customTemplates configuration

User Experience:

  • Clean template editor with expandable variables reference
  • Visual indicators for unsaved changes and save states
  • Comprehensive validation and error messages
  • Sticky navigation and responsive design
  • Individual template save buttons with bulk operations when needed

Supported Notification Types:

  • Media Pending, Approved, Auto-Approved, Available, Declined, Failed
  • Issue Created, Comment, Resolved, Reopened
  • Auto-Requested notifications
  • Test notifications

Screenshot (if UI-related)

Customize Templates button added to email notifications page:
image

Main template management page with multiple notification types:
image

Template editor:
image

Email preview modal showing rendered content:
image
image
image

Custom HTML mode interface:
image

To-Dos

  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required) - No database changes required, uses existing settings system

Issues Fixed or Closed

@gauthier-th

Copy link
Copy Markdown
Member

Did you write this using an AI agent?

@mmenanno

mmenanno commented Sep 3, 2025 •

Copy link
Copy Markdown
Author

Did you write this using an AI agent?

My IDE is cursor so AI helped when I was stuck and helped me find the right files to be editing.

(An AI agent very much wrote the lovely PR description though haha)

@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Sep 8, 2025
@github-actions

github-actions Bot commented Sep 8, 2025

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@mmenanno
mmenanno force-pushed the feature-custom-email-templates branch from a28f34d to 3860758 Compare September 8, 2025 17:34
@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label Sep 8, 2025
@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Oct 4, 2025
@github-actions

github-actions Bot commented Oct 4, 2025

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@M0NsTeRRR

Copy link
Copy Markdown
Member

Hey,

I don’t think we should implement this feature in the proposed way for the following reasons:

  • Custom templating shouldn’t be limited to emails; it should also support other notifications like Discord webhooks.
  • It would be better to use a standard template engine rather than building a custom solution. This would give users more flexibility (e.g., capitalization, formatting) without reinventing the wheel.

Also avoid updating the Helm files directly, as they are managed differently.

Add TemplateEngine class with 17 template variables for dynamic email personalization. Includes
variables like user_name, media_name, request_id, request_url, etc. Supports conditional rendering
and provides foundation for custom templates.

re seerr-team#1876
Add customTemplates object to NotificationAgentEmail interface. Support per-notification-type custom
templates (subject, body, useCustomHtml). Include templates for all notification types:
mediaPending, mediaApproved, mediaAvailable, mediaDeclined, etc.
Add Pug template files for custom email rendering. Includes custom-template for styled emails and
raw-html for fully custom HTML emails. Supports both subject and body template rendering.
Integrate custom template logic into EmailAgent. Add shouldUseCustomTemplate and buildCustomMessage
methods. Support both styled custom templates and raw HTML templates. Remove redundant fallback code
and optimize for performance.

re seerr-team#1876
Add API endpoints for template testing, preview, and variable information. Includes
/email/test-template for sending test emails, /email/preview for template preview, and
/email/template-variables for available variables and defaults.

re seerr-team#1876
Add comprehensive email template editor with per-template customization. Features include toggle
between default/custom modes, live preview, test email functionality, custom HTML support, template
variables reference, and individual/bulk save operations.

re seerr-team#1876
Add API documentation for new email template endpoints: test-template, preview, and
template-variables. Include request/response schemas and proper endpoint definitions.

re seerr-team#1876
@mmenanno
mmenanno force-pushed the feature-custom-email-templates branch from 3860758 to e94ae5a Compare October 12, 2025 22:39
@mmenanno
mmenanno requested a review from a team as a code owner October 12, 2025 22:39
@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label Oct 12, 2025
@mmenanno

Copy link
Copy Markdown
Author

Hey,

I don’t think we should implement this feature in the proposed way for the following reasons:

  • Custom templating shouldn’t be limited to emails; it should also support other notifications like Discord webhooks.
  • It would be better to use a standard template engine rather than building a custom solution. This would give users more flexibility (e.g., capitalization, formatting) without reinventing the wheel.

Also avoid updating the Helm files directly, as they are managed differently.

That is a fair point, is there a preferred standard template engine that I should look at implementing here?

@gauthier-th

Copy link
Copy Markdown
Member

That is a fair point, is there a preferred standard template engine that I should look at implementing here?

I already used handlebars for that kind of templating stuff, but I don't have much preference on this if someone has a better alternative in mind.

It would be better to use a standard template engine rather than building a custom solution. This would give users more flexibility (e.g., capitalization, formatting) without reinventing the wheel.

A custom template system has already been implemented with webhooks, both for the message content and the address (see https://github.com/seerr-team/seerr/blob/develop/server/lib/notifications/agents/webhook.ts).

As we already implemented this custom template system, if it is enough for our use cases we could maybe look into adapting it for all notifications (instead of just the webhooks)?

@mmenanno

Copy link
Copy Markdown
Author

That is a fair point, is there a preferred standard template engine that I should look at implementing here?

I already used handlebars for that kind of templating stuff, but I don't have much preference on this if someone has a better alternative in mind.

It would be better to use a standard template engine rather than building a custom solution. This would give users more flexibility (e.g., capitalization, formatting) without reinventing the wheel.

A custom template system has already been implemented with webhooks, both for the message content and the address (see https://github.com/seerr-team/seerr/blob/develop/server/lib/notifications/agents/webhook.ts).

As we already implemented this custom template system, if it is enough for our use cases we could maybe look into adapting it for all notifications (instead of just the webhooks)?

That makes sense, looking at the options I think it makes the most sense to use Handlebars. The webhook's KeyMap can't handle conditionals or formatting, and my custom engine only has basic conditional support. Handlebars gives us all that plus extensibility without reinventing the wheel.

I'm thinking I would split this work over several PRs:

  1. This PR: Refactor email agent to use Handlebars
  2. Create a shared template variable registry (combine webhook KeyMap + my email variables)
  3. Follow-up PR: Refactor webhook agent to use Handlebars + shared registry
  4. Add per-agent template settings to other agents (Discord, Slack, etc.)
  5. Extend UI to support template management for all agents

Does this align with what you're thinking?

@gauthier-th

Copy link
Copy Markdown
Member

The webhook's KeyMap can't handle conditionals or formatting, and my custom engine only has basic conditional support.

Ah, I didn't see you created a custom engine to do other things than just replacing placeholders. Yes it's either a very simple engine to replace placeholders (like right now), or another lib to handle it.

I'm thinking I would split this work over several PRs:

100% agree. The smaller the PRs, the better. Very big PR like this one are very hard to review.

WDYT of something like this instead:

  1. Refactor the current custom template engine in the webhook notifications to use handlebars
  2. UI to support template management for all agents
  3. Use the new template engine for every notifications

The order of 2. and 3. could be inverted.

@mmenanno

Copy link
Copy Markdown
Author

The webhook's KeyMap can't handle conditionals or formatting, and my custom engine only has basic conditional support.

Ah, I didn't see you created a custom engine to do other things than just replacing placeholders. Yes it's either a very simple engine to replace placeholders (like right now), or another lib to handle it.

I'm thinking I would split this work over several PRs:

100% agree. The smaller the PRs, the better. Very big PR like this one are very hard to review.

WDYT of something like this instead:

  1. Refactor the current custom template engine in the webhook notifications to use handlebars
  2. UI to support template management for all agents
  3. Use the new template engine for every notifications

The order of 2. and 3. could be inverted.

That makes sense to me, I'll get started on converting the web hooks engine to use handlebars

@mmenanno

Copy link
Copy Markdown
Author

First part is up #2039 I put extensive testing instructions to try and make the review process easier.

@M0NsTeRRR

M0NsTeRRR commented Nov 19, 2025 •

Copy link
Copy Markdown
Member

@mmenanno If the PR linked above was meant to be opened directly against seerr, it looks like you accidentally created it in your fork instead.

This one mmenanno#1

@mmenanno

Copy link
Copy Markdown
Author

@M0NsTeRRR it is a stacked PR, so this PR #2039 needs to be merged first. I opened it against my fork just to have the description and such ready for when I can open it against the main repo

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.

Notification content customization

3 participants