diff --git a/lms/djangoapps/course_goals/management/commands/goal_reminder_email.py b/lms/djangoapps/course_goals/management/commands/goal_reminder_email.py index af48472886bb..a9ab150221ea 100644 --- a/lms/djangoapps/course_goals/management/commands/goal_reminder_email.py +++ b/lms/djangoapps/course_goals/management/commands/goal_reminder_email.py @@ -3,6 +3,10 @@ """ import time from datetime import date, datetime, timedelta + +import boto3 +from edx_ace.channel.django_email import DjangoEmailChannel +from edx_ace.channel.mixins import EmailChannelMixin from eventtracking import tracker import logging import uuid @@ -10,10 +14,10 @@ from django.conf import settings from django.contrib.sites.models import Site from django.core.management.base import BaseCommand -from edx_ace import ace +from edx_ace import ace, presentation from edx_ace.message import Message from edx_ace.recipient import Recipient - +from edx_ace.utils.signals import send_ace_message_sent_signal from common.djangoapps.student.models import CourseEnrollment from lms.djangoapps.certificates.api import get_certificate_for_user_id from lms.djangoapps.certificates.data import CertificateStatuses @@ -121,7 +125,11 @@ def send_ace_message(goal, session_id): with emulate_http_request(site, user): try: start_time = time.perf_counter() - ace.send(msg) + if is_ses_enabled: + # experimental implementation to log errors with ses + send_email_using_ses(user, msg) + else: + ace.send(msg) end_time = time.perf_counter() log.info(f"Goal Reminder for {user.id} for course {goal.course_key} sent in {end_time - start_time} " f"using {'SES' if is_ses_enabled else 'others'}") @@ -297,3 +305,46 @@ def handle_goal(goal, today, sunday_date, monday_date, session_id): return True return False + + +def send_email_using_ses(user, msg): + """ + Send email using AWS SES + """ + msg = presentation.render(DjangoEmailChannel, msg) + # send rendered email using SES + sender = EmailChannelMixin.get_from_address(msg) + recipient = user.email + subject = EmailChannelMixin.get_subject(msg) + body_text = msg.body + body_html = msg.body_html + + try: + # Send email + response = boto3.client('ses', settings.AWS_SES_REGION_NAME).send_email( + Source=sender, + Destination={ + 'ToAddresses': [recipient], + }, + Message={ + 'Subject': { + 'Data': subject, + 'Charset': 'UTF-8' + }, + 'Body': { + 'Text': { + 'Data': body_text, + 'Charset': 'UTF-8' + }, + 'Html': { + 'Data': body_html, + 'Charset': 'UTF-8' + } + } + } + ) + + log.info(f"Goal Reminder Email: email sent using SES with message ID {response['MessageId']}") + send_ace_message_sent_signal(DjangoEmailChannel, msg) + except Exception as e: + log.error(f"Goal Reminder Email: Error sending email using SES: {e}") diff --git a/lms/djangoapps/course_goals/management/commands/tests/test_goal_reminder_email.py b/lms/djangoapps/course_goals/management/commands/tests/test_goal_reminder_email.py index 5b98b202d41f..31804037919c 100644 --- a/lms/djangoapps/course_goals/management/commands/tests/test_goal_reminder_email.py +++ b/lms/djangoapps/course_goals/management/commands/tests/test_goal_reminder_email.py @@ -182,8 +182,8 @@ def test_old_course(self, end): self.make_valid_goal(overview__end=end) self.call_command(expect_sent=False) - @mock.patch('lms.djangoapps.course_goals.management.commands.goal_reminder_email.ace.send') - def test_params_with_ses(self, mock_ace): + @mock.patch('lms.djangoapps.course_goals.management.commands.goal_reminder_email.send_email_using_ses') + def test_params_with_ses(self, mock_send_email_using_ses): """Test that the parameters of the msg passed to ace.send() are set correctly when SES is enabled""" with override_waffle_flag(ENABLE_SES_FOR_GOALREMINDER, active=None): goal = self.make_valid_goal() @@ -193,8 +193,8 @@ def test_params_with_ses(self, mock_ace): with freeze_time('2021-03-02 10:00:00'): call_command('goal_reminder_email') - assert mock_ace.call_count == 1 - msg = mock_ace.call_args[0][0] + assert mock_send_email_using_ses.call_count == 1 + msg = mock_send_email_using_ses.call_args[0][1] assert msg.options['override_default_channel'] == 'django_email' assert msg.options['from_address'] == settings.LMS_COMM_DEFAULT_FROM_EMAIL