diff --git a/lms/envs/common.py b/lms/envs/common.py index 2ff6621a0d19..e41a9b131b95 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -5387,10 +5387,13 @@ def _make_locale_paths(settings): # pylint: disable=missing-function-docstring SUBSCRIPTIONS_TRIAL_LENGTH = 7 SUBSCRIPTIONS_SERVICE_WORKER_USERNAME = 'subscriptions_worker' -############## NOTIFICATIONS EXPIRY ############## +############## NOTIFICATIONS ############## NOTIFICATIONS_EXPIRY = 60 EXPIRED_NOTIFICATIONS_DELETE_BATCH_SIZE = 10000 NOTIFICATION_CREATION_BATCH_SIZE = 99 +NOTIFICATIONS_DEFAULT_FROM_EMAIL = "no-reply@example.com" +NOTIFICATION_TYPE_ICONS = {} +DEFAULT_NOTIFICATION_ICON_URL = "" ############################ AI_TRANSLATIONS ################################## AI_TRANSLATIONS_API_URL = 'http://localhost:18760/api/v1' diff --git a/openedx/core/djangoapps/notifications/email/__init__.py b/openedx/core/djangoapps/notifications/email/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/openedx/core/djangoapps/notifications/email/message_type.py b/openedx/core/djangoapps/notifications/email/message_type.py new file mode 100644 index 000000000000..655363248bbe --- /dev/null +++ b/openedx/core/djangoapps/notifications/email/message_type.py @@ -0,0 +1,18 @@ +""" +Email notifications MessageType +""" +from django.conf import settings +from edx_ace.message import MessageType + + +class EmailNotificationMessageType(MessageType): + """ + Edx-ace MessageType for Email Notifications + """ + + NAME = "notifications" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.options['transactional'] = True + self.options['from_address'] = settings.NOTIFICATIONS_DEFAULT_FROM_EMAIL diff --git a/openedx/core/djangoapps/notifications/email/notification_icons.py b/openedx/core/djangoapps/notifications/email/notification_icons.py new file mode 100644 index 000000000000..0336a43a817f --- /dev/null +++ b/openedx/core/djangoapps/notifications/email/notification_icons.py @@ -0,0 +1,45 @@ +""" +Notification Icons +""" +from django.conf import settings + + +class NotificationTypeIcons: + """ + Notification Mapping with icons + """ + CHECK_CIRCLE_GREEN = "CHECK_CIRCLE_GREEN" + HELP_OUTLINE = "HELP_OUTLINE" + NEWSPAPER = "NEWSPAPER" + POST_OUTLINE = "POST_OUTLINE" + QUESTION_ANSWER_OUTLINE = "QUESTION_ANSWER_OUTLINE" + REPORT_RED = "REPORT_RED" + VERIFIED = "VERIFIED" + + @classmethod + def get_icon_name_for_notification_type(cls, notification_type, default="POST_OUTLINE"): + """ + Returns icon name for notification type + """ + notification_type_dict = { + "new_comment_on_response": cls.QUESTION_ANSWER_OUTLINE, + "new_comment": cls.QUESTION_ANSWER_OUTLINE, + "new_response": cls.QUESTION_ANSWER_OUTLINE, + "new_discussion_post": cls.POST_OUTLINE, + "new_question_post": cls.HELP_OUTLINE, + "response_on_followed_post": cls.QUESTION_ANSWER_OUTLINE, + "comment_on_followed_post": cls.QUESTION_ANSWER_OUTLINE, + "content_reported": cls.REPORT_RED, + "response_endorsed_on_thread": cls.VERIFIED, + "response_endorsed": cls.CHECK_CIRCLE_GREEN, + "course_update": cls.NEWSPAPER, + } + return notification_type_dict.get(notification_type, default) + + @classmethod + def get_icon_url_for_notification_type(cls, notification_type): + """ + Returns icon url for notification type + """ + icon_name = cls.get_icon_name_for_notification_type(notification_type) + return settings.NOTIFICATION_TYPE_ICONS.get(icon_name, settings.DEFAULT_NOTIFICATION_ICON_URL) diff --git a/openedx/core/djangoapps/notifications/email/utils.py b/openedx/core/djangoapps/notifications/email/utils.py new file mode 100644 index 000000000000..2993b68fc2dd --- /dev/null +++ b/openedx/core/djangoapps/notifications/email/utils.py @@ -0,0 +1,64 @@ +""" +Email Notifications Utils +""" +from django.conf import settings +from lms.djangoapps.branding.api import get_logo_url_for_email +from .notification_icons import NotificationTypeIcons + + +def create_datetime_string(datetime_instance): + return datetime_instance.strftime('%A, %b %d') + + +def get_icon_url_for_notification_type(notification_type): + """ + Returns icon url for notification type + """ + return NotificationTypeIcons.get_icon_url_for_notification_type(notification_type) + + +def create_email_template_context(): + """ + Creates email context for header and footer + """ + social_media_urls = settings.SOCIAL_MEDIA_FOOTER_ACE_URLS + social_media_icons = settings.SOCIAL_MEDIA_LOGO_URLS + social_media_info = { + social_platform: { + 'url': social_media_urls[social_platform], + 'icon': social_media_icons[social_platform] + } + for social_platform in social_media_urls.keys() + if social_media_icons.get(social_platform) + } + return { + "platform_name": settings.PLATFORM_NAME, + "mailing_address": settings.CONTACT_MAILING_ADDRESS, + "logo_url": get_logo_url_for_email(), + "social_media": social_media_info, + "notification_settings_url": f"{settings.ACCOUNT_MICROFRONTEND_URL}/notifications", + } + + +def create_email_digest_content(start_date, end_date=None, digest_frequency="Daily", + notifications_count=0, updates_count=0, email_content=None): + """ + Creates email context based on content + start_date: datetime instance + end_date: datetime instance + """ + context = create_email_template_context() + start_date_str = create_datetime_string(start_date) + end_date_str = create_datetime_string(end_date if end_date else start_date) + context.update({ + "start_date": start_date_str, + "end_date": end_date_str, + "digest_frequency": digest_frequency, + "updates": [ + {"count": updates_count, "type": "Updates"}, + {"count": notifications_count, "type": "Notifications"} + ], + "email_content": email_content if email_content else [], + "get_icon_url_for_notification_type": get_icon_url_for_notification_type, + }) + return context diff --git a/openedx/core/djangoapps/notifications/templates/notifications/digest_content.html b/openedx/core/djangoapps/notifications/templates/notifications/digest_content.html new file mode 100644 index 000000000000..aa1ee903ad7e --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/digest_content.html @@ -0,0 +1,55 @@ +{% for update in email_content %} +

+ {{ update.title }} +

+ {% if update.help_text %} +

+ + {{ update.help_text }} + + {% if update.help_text_url %} + + + View all + + + {% endif %} +

+ {% endif %} +

+

+ + + {% for content in update.content %} + + + + + {% endfor %} + +
+ + +

+ {{ content.title }} +

+

+

+ + {{ content.course_name }} + · + {{ content.time_ago }} + + + + View + + +

+
+

+

+{% endfor %} diff --git a/openedx/core/djangoapps/notifications/templates/notifications/digest_footer.html b/openedx/core/djangoapps/notifications/templates/notifications/digest_footer.html new file mode 100644 index 000000000000..bcd5c0849346 --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/digest_footer.html @@ -0,0 +1,48 @@ + + + + + + + + + +
+ + + + + + + +
+ Logo + + + + + {% for social_name, social_data in social_media.items %} + + {% endfor %} + + +
+ + {{social_name}} + +
+
+
+

+ You are receiving this email because you have subscribed to email digest +

+

+ + Notification Settings + +

+

+ © {% now "Y" %} {{ platform_name }}. All Rights Reserved
+ {{ mailing_address }} +

+
diff --git a/openedx/core/djangoapps/notifications/templates/notifications/digest_header.html b/openedx/core/djangoapps/notifications/templates/notifications/digest_header.html new file mode 100644 index 000000000000..fc91d77fa0bf --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/digest_header.html @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + +
+ logo_url +
+ {{ digest_frequency }} email digest +
+ {{ start_date }} {% if digest_frequency == "Weekly" %} - {{ end_date }} {% endif %} +
+ + + + {% for update in updates %} + + {% endfor %} + + +
+

+ + + + + + + + + +
+ {{update.count}} +
+ {{update.type}} +
+

+
+
diff --git a/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.html b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.html new file mode 100644 index 000000000000..c847f75e4f7b --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.html @@ -0,0 +1 @@ +<%page expression_filter="h"/> diff --git a/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.txt b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.txt new file mode 100644 index 000000000000..e45fd8029e2d --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/body.txt @@ -0,0 +1,22 @@ +

+ + + + + + + + + + + + +
+ {% include 'notifications/digest_header.html' %} +
+ {% include 'notifications/digest_content.html' %} +
+ {% include 'notifications/digest_footer.html' %} +
+ +
diff --git a/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/from_name.txt b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/from_name.txt new file mode 100644 index 000000000000..dcbc23c00480 --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/from_name.txt @@ -0,0 +1 @@ +{{ platform_name }} diff --git a/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/head.html b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/head.html new file mode 100644 index 000000000000..c847f75e4f7b --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/head.html @@ -0,0 +1 @@ +<%page expression_filter="h"/> diff --git a/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/subject.txt b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/subject.txt new file mode 100644 index 000000000000..3bbe26faf772 --- /dev/null +++ b/openedx/core/djangoapps/notifications/templates/notifications/edx_ace/email_digest/email/subject.txt @@ -0,0 +1 @@ +{{ digest_frequency }} Notifications Digest for {% if digest_frequency == "Weekly" %}the Week of {% endif %}{{ start_date }}