Skip to content

Commit 46c7f6d

Browse files
fix: bypass edx ace for sending goal reminder email using ses (openedx#36148)
1 parent a5b9b87 commit 46c7f6d

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

lms/djangoapps/course_goals/management/commands/goal_reminder_email.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
"""
44
import time
55
from datetime import date, datetime, timedelta
6+
7+
import boto3
8+
from edx_ace.channel.django_email import DjangoEmailChannel
9+
from edx_ace.channel.mixins import EmailChannelMixin
610
from eventtracking import tracker
711
import logging
812
import uuid
913

1014
from django.conf import settings
1115
from django.contrib.sites.models import Site
1216
from django.core.management.base import BaseCommand
13-
from edx_ace import ace
17+
from edx_ace import ace, presentation
1418
from edx_ace.message import Message
1519
from edx_ace.recipient import Recipient
16-
20+
from edx_ace.utils.signals import send_ace_message_sent_signal
1721
from common.djangoapps.student.models import CourseEnrollment
1822
from lms.djangoapps.certificates.api import get_certificate_for_user_id
1923
from lms.djangoapps.certificates.data import CertificateStatuses
@@ -121,7 +125,11 @@ def send_ace_message(goal, session_id):
121125
with emulate_http_request(site, user):
122126
try:
123127
start_time = time.perf_counter()
124-
ace.send(msg)
128+
if is_ses_enabled:
129+
# experimental implementation to log errors with ses
130+
send_email_using_ses(user, msg)
131+
else:
132+
ace.send(msg)
125133
end_time = time.perf_counter()
126134
log.info(f"Goal Reminder for {user.id} for course {goal.course_key} sent in {end_time - start_time} "
127135
f"using {'SES' if is_ses_enabled else 'others'}")
@@ -297,3 +305,46 @@ def handle_goal(goal, today, sunday_date, monday_date, session_id):
297305
return True
298306

299307
return False
308+
309+
310+
def send_email_using_ses(user, msg):
311+
"""
312+
Send email using AWS SES
313+
"""
314+
msg = presentation.render(DjangoEmailChannel, msg)
315+
# send rendered email using SES
316+
sender = EmailChannelMixin.get_from_address(msg)
317+
recipient = user.email
318+
subject = EmailChannelMixin.get_subject(msg)
319+
body_text = msg.body
320+
body_html = msg.body_html
321+
322+
try:
323+
# Send email
324+
response = boto3.client('ses', settings.AWS_SES_REGION_NAME).send_email(
325+
Source=sender,
326+
Destination={
327+
'ToAddresses': [recipient],
328+
},
329+
Message={
330+
'Subject': {
331+
'Data': subject,
332+
'Charset': 'UTF-8'
333+
},
334+
'Body': {
335+
'Text': {
336+
'Data': body_text,
337+
'Charset': 'UTF-8'
338+
},
339+
'Html': {
340+
'Data': body_html,
341+
'Charset': 'UTF-8'
342+
}
343+
}
344+
}
345+
)
346+
347+
log.info(f"Goal Reminder Email: email sent using SES with message ID {response['MessageId']}")
348+
send_ace_message_sent_signal(DjangoEmailChannel, msg)
349+
except Exception as e:
350+
log.error(f"Goal Reminder Email: Error sending email using SES: {e}")

lms/djangoapps/course_goals/management/commands/tests/test_goal_reminder_email.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ def test_old_course(self, end):
182182
self.make_valid_goal(overview__end=end)
183183
self.call_command(expect_sent=False)
184184

185-
@mock.patch('lms.djangoapps.course_goals.management.commands.goal_reminder_email.ace.send')
186-
def test_params_with_ses(self, mock_ace):
185+
@mock.patch('lms.djangoapps.course_goals.management.commands.goal_reminder_email.send_email_using_ses')
186+
def test_params_with_ses(self, mock_send_email_using_ses):
187187
"""Test that the parameters of the msg passed to ace.send() are set correctly when SES is enabled"""
188188
with override_waffle_flag(ENABLE_SES_FOR_GOALREMINDER, active=None):
189189
goal = self.make_valid_goal()
@@ -193,8 +193,8 @@ def test_params_with_ses(self, mock_ace):
193193
with freeze_time('2021-03-02 10:00:00'):
194194
call_command('goal_reminder_email')
195195

196-
assert mock_ace.call_count == 1
197-
msg = mock_ace.call_args[0][0]
196+
assert mock_send_email_using_ses.call_count == 1
197+
msg = mock_send_email_using_ses.call_args[0][1]
198198
assert msg.options['override_default_channel'] == 'django_email'
199199
assert msg.options['from_address'] == settings.LMS_COMM_DEFAULT_FROM_EMAIL
200200

0 commit comments

Comments
 (0)