User notifications
Introduces the User Notifications framework in Optimizely, intended for sending user-to-user notification messages.
The user notification framework in CMS 13 sends targeted messages between users through a channel-based system. Use it to notify editors about content changes, approval workflows, or custom events.
A sender posts a message on a named channel to one or more recipients. The system stores posted messages and dispatches them through a formatter and a provider. The formatter transforms message text and retrieves related content or user data as needed. Formatters also group messages to reduce the total delivered to each recipient. The provider delivers the formatted message through a specific method, such as email. Each channel supports multiple providers, and recipients choose their preferred provider.
Post a message to INotifier for immediate delivery or for the scheduled job queue. The NotificationDispatcher retrieves queued messages, formats them with a NotificationFormatter, and delivers them through a NotificationProvider. Create custom formatters and providers to extend delivery behavior.
Every message belongs to a channel, a namespace that groups messages of a certain kind and keeps them separate. Create a custom channel by defining a name and providing a supporting formatter. To enable immediate processing for a channel, add a NotificationChannelOptions instance to INotificationChannelOptionsRegistry. The scheduler processes messages periodically by default.
The sender does not control how the recipient receives the message. The recipient's provider preferences for that channel determine the delivery method.
NoteDo not use generic names for channels, providers, and formatters because they risk colliding with other names. Prefix the names with something unique.
Message types
Three message types control when the system processes a notification:
NotificationMessage– Processes the message at the next scheduled job or immediately, depending on the registered channel options.ScheduledNotificationMessage– Processes the message at the next scheduled job after a specified time.DelayedNotificationMessage– Processes the message at the next scheduled job after a delay period rather than a fixed time.
Users
Identify notification recipients and senders through their INotificationUser identity, which carries a name and a display name. Retrieve a QueryableNotificationUserService instance to search for users. Call FindAsync to search by partial name or GetAsync to retrieve a specific user by name.
User preferences
Provider preferences determine how each user receives notifications per channel. Register a default preference resolver for a channel and provider through INotificationPreferenceRegister. The resolver accepts a username and returns a provider-specific address, such as an email address for the email provider.
Post notifications
The INotifier interface queues messages for delivery to one or more recipients. Call PostNotificationAsync to post a message. A message with multiple recipients creates one internal message per recipient. Subscribe to the NotificationPosted, NotificationSaved, and NotificationFiltered events to track posting results per message.
Dispatch notifications
The NotificationDispatcher retrieves queued messages and groups them by recipient and channel. For each group, the dispatcher locates a matching formatter and provider, then formats and delivers the messages. Failed messages return to the queue for retry.
The scheduler triggers the dispatcher, or the system calls it directly for immediate messages.
Formatters
Formatters transform messages before delivery and control how the system prepares content for each provider. Each formatter has a name and a list of supported channel names. The dispatcher selects the formatter whose supported names match the message channel.
NoteIf more than one formatter matches the channel name, the system sends no message and logs an error.
For implementation details, see the following section.
Build custom formatters
Create a custom formatter by implementing the INotificationFormatter interface. Assign it a name and a list of supported channels. The FormatMessagesAsync method accepts and returns a list of messages. In the simplest case, return the incoming messages unchanged.
The formatter combines multiple messages into one by setting ContainedID to match the IDs of the combined messages. The system treats any input message ID absent from the output as completed and removes it from the queue. If formatting fails, the formatter throws an exception. The system returns those messages to the queue for the next scheduled job.
Providers
Providers deliver notifications through a specific communication method, giving each channel flexibility in how it reaches users. The built-in EmailNotificationProvider handles email delivery. For configuration details, see Configure your email server. Each provider has a name and a format property. The format property specifies constraints such as maximum length and HTML support.
Implement INotificationProvider to build a custom provider. Optionally implement INotificationProviderStatus to enable or disable the provider at runtime. The SendAsync method handles delivery. Call succeededAction or failedAction for each message.
List notifications
The IUserNotificationRepository interface retrieves notification data for display in the Optimizely UI. Call GetUserNotificationAsync, GetUserNotificationsAsync, or GetUserNotificationsCountAsync to retrieve notifications.
Implement IUserNotificationFormatter for one or more channels to return formatted messages. The formattingMode parameter on GetUserNotification(s)Async controls formatting behavior.
Subscribe to the UserNotificationMissing event to receive a callback when the system cannot locate a notification.
Mark notifications as read
The IUserNotificationRepository interface also marks notifications as read. Call one of the MarkUserNotification(s)AsReadAsync methods to update read status. Subscribe to the UserNotificationRead and UserNotificationReads events to track read-status changes.
Truncate the message queue
Old notifications accumulate in the database over time. The Notification Message Truncate scheduled job runs every night by default and removes notifications older than three months.
Retry and undeliverable notifications
The notification system limits retry attempts for failed messages and marks them as undeliverable when retries are exhausted. This prevents failed messages from blocking the queue indefinitely.
Database fields for retry tracking
The tblNotificationMessage table stores retry state in the following fields:
Failed– Stores the timestamp of the most recent failed send attempt. The dispatcher uses this value to determine when to retry.RetriesLeft– Stores the remaining number of retry attempts.
Retry processing
The dispatcher applies the following logic when processing messages:
- Filter out notifications where
RetriesLeftequals zero. - Include previously failed notifications only after the retry delay passes.
- Decrement
RetriesLeftwhen a send attempt fails. - Update the
Failedtimestamp to reflect the allowed retry time.
When RetriesLeft reaches zero, the system marks the notification as undeliverable and stops retrying.
Retry intervals
The retry delay increases with each failed attempt:
RetriesLeft | Retry delay |
|---|---|
| 3 | 1 minute |
| 2 | 5 minutes |
| 1 | 60 minutes |
| 0 | No retry |
Error handling for providers
Notification providers must throw an exception when a send operation fails. The retry mechanism relies on the exception to take the following actions:
- Decrement
RetriesLeft. - Schedule the next retry attempt.
- Mark the notification as undeliverable when retries are exhausted.
Updated 17 days ago
