How to create a new notification
Creating Configurations:
This documentation provides instructions on how to add new notifications to the existing notification system. The configuration consists of notification types and notification apps. Follow the steps below to add a new notification.
Step 1: Define the Notification App
To associate the notification type with an app, define the app as follows in this file
COURSE_NOTIFICATION_APPS = {
'discussion': {
'enabled': <True/False>,
'core_info': '<core_info>', # Core info description
'core_web': <True/False>, # Enable web delivery for core notifications
'core_email': <True/False>, # Enable email delivery for core notifications
'core_push': <True/False>, # Enable push delivery for core notifications
'non_editable': [] # Channels that user cannot edit allowed values 'web', 'email', 'push'
}
}
App name can be any name you wish to add but ideally it should represent existing Django apps in the project.
Explanation of the fields:
enabled(required): Set toTrueto enable the app for notifications. (As per product decision, we have hidden app level toggle from frontend).core_info(optional): Provide an optional description for core notifications. (for more info about core notifications refer to core notification part of this doc)core_web,core_email, andcore_push(mandatory): Set toTrueto enable respective delivery channels for core notifications. (Sending push notifications is under development)non_editable(required): This field is used to control if some channels of core notification are not editable by the user.core_email_cadence(required): This field is used to control the email frequency if core_email is set to True its value could be daily, weekly or immediately
Step 2: Define the Notification Type
To add a new notification type, follow the structure below:
Here is a file that contains these settings
https://github.com/openedx/edx-platform/blob/cd6c7541987016494e39909437b837a5a2c0c426/openedx/core/djangoapps/notifications/base_notification.py#L11 :
COURSE_NOTIFICATION_TYPES = {
....
'new_comment_on_response':{
'notification_app': '<app_name>',
'name': '<notification_type>',
'is_core': <True/False>,
'web': <True/False>,
'email': <True/False>,
'email_cadence': <EmailCadence.DAILY / EmailCadence.WEEKLY>,
'push': <True/False>,
'info': '<notification_info>',
'non_editable': ['web', 'email', 'push'], # List of non-editable delivery channels
'content_template': _('<content_template_translation>'),
'grouped_content_template': _('content_template_for_grouped_notification'),
'content_context': {
'<context_variable_1>': '<context_variable_1_description>',
'<context_variable_2>': '<context_variable_2_description>',
...
},
'filters': [FILTER_AUDIT_EXPIRED],
'email_template': '<email_template>', # Optional email template if applicable
}
}
notification_app(required): Specify the app to which the notification belongs. It should match one of the entries inCOURSE_NOTIFICATION_APPS.name(required): Provide a unique name for the notification type.is_core(required): Set toTrueif the notification is of the core type, otherwiseFalse. (for more info about core notifications refer to core notification part of this doc)web,email, andpush(required if not core notification): Set toTrueif the notification type supports the respective delivery channels, otherwiseFalse.email_cadence: Frequency to send these notifications in email digest.info(required): Briefly describe the purpose of the notification type.non_editable(optional): If certain delivery channels should be non-editable, list them here. Available options:'web','email','push'.content_template(required): Provide the translated content template for the notification type. Use_(...)to mark translatable parts. (view Template specification section)grouped_content_template(required): Provide the translated content template for the grouped notification. Use _(...) to mark translatable parts. (view Template specification section)content_context(required): Define the variables used in the content template and their descriptions.'filters':(optional): Type (list) Set it to[FILTER_AUDIT_EXPIRED]in this case notification would not be sent to the learner with audit access expired.email_template(optional): If the notification type includes an email template, provide it here.
push channel has not been implemented. Currently, web and email channels are working
Step 3: Update the version in the model file
Newly added types are only useable once you have updated the value of this constant, this constant is used to track changes in notification configuration. and whenever this version is updated preferences of users are also updated with newly available types. to update use the previous value +1.
This step is mandatory without it adding new configs will have no effect. (We don’t need to update config version for changes that are not stored in database e.g. template)
COURSE_NOTIFICATION_CONFIG_VERSION = 1Core notifications
Core notifications are grouped together with a single switch on the front end. Users can enable/disable all core notifications with only one click
To create a core notification all you need to do is add 'is_core': True in notification configurations.
For core notifications, you don't have to define channel default configurations i.e. web, push, and email configurations for core notifications are added on the app level i.e. core_web, core_email, core_push
Any of them can be made non-editable by adding them to the app config i.e. 'non_editable':['web', 'push']
Template Specifications :
Provide the translated content template for the notification type. Use _(...) to mark translatable parts.
make sure to add content in <p> ... </p> tags , user <strong> to make words bold in templates . make note that only <p> and <strong> are supported .
Translating Templates
Ensure that the content templates and email templates are properly translated. The gettext_lazy() function is used to mark translatable parts. Modify the translations accordingly.
Note: Make sure to import the gettext_lazy function from the appropriate translation module.
Example:
from django.utils.translation import gettext_lazy as _
COURSE_NOTIFICATION_TYPES['new_notification_type']['content_template'] = _('<{p}><{strong}>Translated Content</{strong}></{p}>')Remember to provide translations for all the supported languages.
That's it! You have successfully added a new notification type to the system. Ensure that all translations and configurations are accurate before deploying the updated code.
2. Creating a notification:
You have to send USER_NOTIFICATION_REQUESTED signal to trigger a code that sends notifications.
To send a new user notification using the USER_NOTIFICATION_REQUESTED signal. Follow the steps below to implement the new notification.
Step 1: Import Dependencies
Make sure to import the necessary dependencies at the beginning of your module:
from openedx_events.learning.signals import USER_NOTIFICATION_REQUESTED
from openedx_events.learning.data import UserNotificationData
Step 2: Implement the send_notification Method
Define the send_notification method in your class or module to send the user notification. The method can be implemented something like this:
In essence, you have to send USER_NOTIFICATION_REQUESTED signal with UserNotificationData Please check out this implementation to find more about required fields in data.
def send_notification(self, user_ids, notification_type, extra_context=None):
"""
Send notification to users.
"""
if not user_ids:
return
if extra_context is None:
extra_context = {}
notification_data = UserNotificationData(
user_ids=user_ids,
context={
'<context_variable_1>': '<context_variable_1_value>',
'<context_variable_2>': '<context_variable_2_value>',
...
**extra_context,
},
notification_type=notification_type,
content_url='<content_url>',
app_name='<app_name>',
course_key='<course_key>',
)
USER_NOTIFICATION_REQUESTED.send_event(notification_data=notification_data)
Explanation of the parameters:
user_ids(required): A list of user IDs to send the notification to.notification_type(required): The type of notification can be a newly created type.context(required): This will replace variables in your template.extra_context(optional): Additional context variables specific to the notification type.
Replace <context_variable_1>, <context_variable_1_value>, <content_url>, <app_name>, and <course_key> with the appropriate values for your notification
That's it! You have implemented the code to send a new user notification using the USER_NOTIFICATION_REQUESTED signal. Ensure that the necessary data and context variables are correctly provided before triggering the notification.
Grouping notification
For some notification types, the volume for a learner can be huge and can cause annoyance. For example, if a learner creates a post, and other learners and staff members start adding responses to his post, if for each comment, we add a response, it could result in dozens of notifications. To avoid these scenarios, we have implemented a feature that allows grouping more than one similar notifications into a single notification. Steps to group a notification
Enable grouping waffle flag
notifications.enable_notification_grouping.Add
group_by_idin context before sending theUSER_NOTIFICATION_REQUESTEDevent (See here).Implement a grouper class to modify content_context (See here)
Legal
When adding a new notification type, you will need a Privacy threshold assessment done by legal.
Waffle Flags
For the list of all available waffle flags, view the following document
https://2u-internal.atlassian.net/wiki/spaces/ENGAGE/pages/670138950
How to Enable Notification Tray
On the front end, the notification tray needs to be enabled to simplify the user experience. Users can click the bell icon in the header to access the notification tray, which will display notifications from the apps listed above. For detailed steps please view the following document
https://2u-internal.atlassian.net/wiki/x/YgBdMg
And explicit implementation of the notification tray on the Learning Dashboard can be viewed in the following document:
https://2u-internal.atlassian.net/wiki/x/DoAmM
Troubleshooting
If you have followed the above steps and notifications are still not working, check if notifications.enable_notifications flag is enabled.