Skip to content

Conversation

@ajayakkalasetti
Copy link
Member

Summary

Introduces an opt-in Course Waffle Flag to enable sending Course Update emails via AWS SES.

Details

  • Added course_experience.enable_ses_for_courseupdate waffle flag (default: disabled).
  • Updated schedule email delivery logic to route Course Update emails through SES when the flag is enabled for the course.
  • Preserves existing behavior for all other scheduled emails.

Testing

  • Verified locally via Django shell:
    • Course Update emails use SES when the flag is enabled.
    • Course Update emails fall back to the default ACE channel when disabled.
    • Recurring Nudge and other schedule emails remain unaffected.

Rollout

  • Flag-controlled and opt-in per course.
  • No behavior change unless explicitly enabled.

@asharma4-sonata Please review my PR and let me know if any changes need to be done.

@asharma4-sonata
Copy link

Unit tests are failing. Pls check.

@ajayakkalasetti ajayakkalasetti force-pushed the feature/course-update-ses-delivery branch 2 times, most recently from d1aa330 to 45a97f3 Compare January 28, 2026 09:38
@ajayakkalasetti ajayakkalasetti marked this pull request as ready for review January 28, 2026 10:33
with emulate_http_request(site=site, user=user):
_annonate_send_task_for_monitoring(msg)
LOG.debug('%s: Sending message = %s', log_prefix, msg_str)
is_ses_enabled = (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for determining is_ses_enabled is starting to grow. To keep _schedule_send clean and ensure we can reuse this logic in other tasks (like send_activation_email), I suggest pulling this into a helper function like should_route_to_ses(msg, course_key=None) placed in openedx/core/djangoapps/ace_common/utils.py

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. I’ve refactored the SES routing logic into a reusable helper should_route_to_ses(...) and moved it to openedx/core/djangoapps/ace_common/utils.py as suggested. _schedule_send is now cleaner and uses this helper.

msg = Message.from_string(msg_str)
msg.options['skip_disable_user_policy'] = True
course_ids = msg.context.get('course_ids', [])
course_key = (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we trying to choose SES route based on a course?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SES routing is not course-based. The delivery path is determined by the environment-driven delivery_config_var (deliver_course_update) and applies uniformly to course update emails.

'override_default_channel': 'django_email',
'transactional': True,
})
ace.send(msg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure the account activation flow is resilient, we should implement a safe fallback pattern. If the Waffle flag is enabled but the SES fails due to a configuration or network issue, the current code will throw an exception and the email will never be sent. By wrapping the SES attempt in a try/except and reverting the options on failure, we ensure the user still receives their email via the default ACE path

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented a safe fallback pattern around the SES send. If SES fails with a recoverable error, the exception is raised for retry.

Copy link

@asharma4-sonata asharma4-sonata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ajayakkalasetti Please find review details in inline comments.

@ajayakkalasetti ajayakkalasetti force-pushed the feature/course-update-ses-delivery branch from 45a97f3 to 95368b5 Compare January 29, 2026 12:52
@ajayakkalasetti ajayakkalasetti force-pushed the feature/course-update-ses-delivery branch from 95368b5 to 524938a Compare January 29, 2026 13:21

try:
ace.send(msg)
except RecoverableChannelDeliveryError:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crazy software might raise a standard Exception rather than a specific ACE error. If we don't catch that, the email won't fall back—it will just fail the task.

log_prefix,
user.id,
)
raise

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a fallback flag that allows emails to be sent through the ACE default route if SES fails. The ultimate goal is to ensure the user always receives the email. We can disable the Braze route once we fully transition away from Braze

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants