Skip to content

feat: add RootEmailNotificationPlugin#1085

Open
stevenle wants to merge 2 commits into
mainfrom
claude/add-email-notification-plugin-142Ev
Open

feat: add RootEmailNotificationPlugin#1085
stevenle wants to merge 2 commits into
mainfrom
claude/add-email-notification-plugin-142Ev

Conversation

@stevenle
Copy link
Copy Markdown
Member

@stevenle stevenle commented May 4, 2026

Summary

This PR introduces a comprehensive email notification system for Root CMS, including a new RootEmailNotificationPlugin that sends emails when CMS actions occur, along with task subscriber management features in the UI.

Key Changes

Email Notification Plugin (email-notification-plugin.ts)

  • New RootEmailNotificationPlugin factory that creates a CMSNotificationService for sending emails on CMS actions
  • Supports flexible recipient specification:
    • Direct email addresses
    • Role-based recipients (e.g., role:ADMIN, role:ADMINS)
    • Task subscribers and mentions via task:subscribers
    • Custom functions for dynamic recipient resolution
  • Action filtering with include/exclude patterns and glob matching (e.g., tasks.*)
  • Template system with variable interpolation ({{action}}, {{by}}, {{metadata.*}}, etc.)
  • Per-action template lookup with fallback to default template
  • User preference support to honor opt-outs via EmailPreferences docs
  • Automatic actor exclusion (configurable)

Email Client (email-client.ts)

  • New EmailClient class for queuing emails to Firestore
  • Writes to Projects/<projectId>/Emails collection with pending status
  • Supports CC, BCC, reply-to, HTML body, and custom tags
  • Configurable TTL (defaults to 24h) for email expiration
  • Deduplication and normalization of email addresses

Task Subscriber Management

  • New subscribers field on Task documents (array of lowercase emails)
  • subscribeToTask() and unsubscribeFromTask() functions for managing subscriptions
  • isUserSubscribedToTask() helper to check subscription status
  • extractMentions() function to parse @email mentions from comments and rich text
  • Automatic mention extraction when adding/editing task comments

UI Components

  • TaskSubscribeButton: Inline button to toggle current user's subscription
  • TaskSubscribersPanel: Sidebar panel showing subscriber list with add/remove functionality
  • New styling for subscriber management UI

Email Worker Enhancement

  • Updated Go email worker to support CC field when processing pending emails

Package Configuration

  • Exported new entry points: @blinkk/root-cms/email-client and @blinkk/root-cms/email-notification
  • Updated tsup config to build new modules

Notable Implementation Details

  • Email addresses are normalized to lowercase for consistency
  • Recipient resolution is async and supports both sync and async functions
  • Template interpolation supports nested metadata paths (e.g., {{metadata.taskId}})
  • Task subscribers include explicit subscribers, assignee, creator, and mentioned users
  • Wildcard role patterns (e.g., *@example.com) are excluded from role-based recipients
  • Email preferences are read in parallel for performance
  • Comprehensive test coverage for plugin functionality and mention extraction

https://claude.ai/code/session_01JSn1UwdSeg9oDqfgJ4yBup

Adds a notification service that sends email when CMS actions occur,
plus a standalone EmailClient for sending email from arbitrary
server-side code.

- New `RootEmailNotificationPlugin` factory at
  `@blinkk/root-cms/email-notification`. Subscribes to `onAction()` via
  the existing notification service hook.
- Recipients can be email addresses, role specifiers (e.g.
  `'role:ADMINS'`), or functions; user-configurable filters
  (`include`/`exclude` globs or a function) gate which actions trigger
  email.
- Plain-text email templates with `{{var}}` interpolation, looked up
  per-action and via prefix glob (e.g. `'tasks.*'`).
- New `EmailClient` at `@blinkk/root-cms/email-client` queues email
  documents in Firestore for delivery by the existing root-services
  Go worker. Adds cc/bcc/replyTo support to the worker.
- Tasks special case: for `tasks.*` actions, subscribers stored on the
  task doc and `@<email>` mentions extracted from comments are
  automatically notified.
- Adds `subscribers` field to `Task`, with subscribe/unsubscribe API
  and UI controls in the task detail page; comment authors are
  auto-subscribed.

https://claude.ai/code/session_01JSn1UwdSeg9oDqfgJ4yBup
@stevenle stevenle changed the title Add email notification plugin and task subscriber management feat: add RootEmailNotificationPlugin May 4, 2026
@stevenle stevenle added the v3 Root v3 release label May 7, 2026
Adds an opt-in plugin wrapper at docs/plugins/email-notifications.ts and
wires it into docs/root.config.ts so the email notification plugin can
be tested end-to-end on rootjs.dev.

- The plugin is enabled when EMAIL_NOTIFICATIONS_FROM is set; otherwise
  the plugin is omitted so local dev keeps working without extra setup.
- Recipients are configurable via EMAIL_NOTIFICATIONS_RECIPIENTS
  (comma-separated emails or role:NAME refs); defaults to role:ADMIN.
- Includes templates for doc.publish, tasks.create, tasks.comment.add,
  and a tasks.* fallback so we can verify each path.
- Adds a small dev script (scripts/test_email_notification.mjs) that
  triggers a synthetic action via RootCMSClient.logAction, useful to
  inspect the queued email doc in Firestore.

https://claude.ai/code/session_01JSn1UwdSeg9oDqfgJ4yBup
Base automatically changed from alpha to main May 12, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v3 Root v3 release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants