Skip to content

feat: add SES routing for account activation emails with fallback support#207

Draft
nthriveni-sonata-ship-it wants to merge 1 commit intoedx:release-ulmofrom
nthriveni-sonata-ship-it:feature/account-activation-ses-routing
Draft

feat: add SES routing for account activation emails with fallback support#207
nthriveni-sonata-ship-it wants to merge 1 commit intoedx:release-ulmofrom
nthriveni-sonata-ship-it:feature/account-activation-ses-routing

Conversation

@nthriveni-sonata-ship-it
Copy link
Copy Markdown
Member

Summary

Adds feature-flagged SES routing for account activation emails with a safe fallback mechanism.

Changes

  • Centralized SES routing logic in ace_common/utils.py
  • Removed SES logic from management view
  • Added fallback handling in send_activation_email task
  • Introduced WaffleFlag: user_authn.enable_ses_for_account_activation

Behavior

  • Flag OFF → default ACE flow
  • Flag ON → SES routing via django_email
  • If SES fails → fallback to default ACE channel

Testing

  • Verified default flow with flag OFF
  • Verified SES routing with flag ON
  • Simulated SES failure and confirmed fallback to default ACE channel

@nthriveni-sonata-ship-it nthriveni-sonata-ship-it force-pushed the feature/account-activation-ses-routing branch from 4aeff43 to d52602d Compare April 2, 2026 06:17
@nthriveni-sonata-ship-it nthriveni-sonata-ship-it force-pushed the feature/account-activation-ses-routing branch from d52602d to 83ef742 Compare April 2, 2026 06:58
Comment on lines +81 to +92
if route_via_ses:
msg.options.update({
'override_default_channel': 'django_email',
'transactional': True,
'from_address': configuration_helpers.get_value(
'ACTIVATION_EMAIL_FROM_ADDRESS'
) or configuration_helpers.get_value(
'email_from_address',
settings.DEFAULT_FROM_EMAIL
),
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have a very naive question: what happens if there is no Braze campaign ID in edx-internal? Would edx-ace know to default to django_email? Or did we still need to explicitly define this as a transactional email in order for AWS SES to be used?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I made this comment and then immediately realized that we do want to default back to using Braze if AWS SES fails. Can you point to where that's happening in the code exactly?

)
return

_remove_ses_overrides(msg)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fallback happens in the except RecoverableChannelDeliveryError block.

Specifically:

  • We remove SES overrides via _remove_ses_overrides(msg)
  • Then call ace.send(msg) again

That second ace.send(msg) routes via the default ACE channel (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.

2 participants