diff --git a/ecommerce_worker/configuration/base.py b/ecommerce_worker/configuration/base.py index 86663922..7c12af6e 100644 --- a/ecommerce_worker/configuration/base.py +++ b/ecommerce_worker/configuration/base.py @@ -85,6 +85,10 @@ 'CAMPAIGN_SEND_ENDPOINT': '/campaigns/trigger/send', 'FROM_EMAIL': '', 'ENTERPRISE_CAMPAIGN_ID': '', + 'ENTERPRISE_CODE_ASSIGNMENT_CAMPAIGN_ID': '', + 'ENTERPRISE_CODE_UPDATE_CAMPAIGN_ID': '', + 'ENTERPRISE_CODE_USAGE_CAMPAIGN_ID': '', + 'ENTERPRISE_CODE_NUDGE_CAMPAIGN_ID': '', # Retry settings for Braze celery tasks 'BRAZE_RETRY_SECONDS': 3600, 'BRAZE_RETRY_ATTEMPTS': 6, diff --git a/ecommerce_worker/email/v1/braze/client.py b/ecommerce_worker/email/v1/braze/client.py index e2854700..f0907ee4 100644 --- a/ecommerce_worker/email/v1/braze/client.py +++ b/ecommerce_worker/email/v1/braze/client.py @@ -295,6 +295,7 @@ def send_message( # pylint: disable=dangerous-default-value sender_alias='EdX Support Team', reply_to='', attachments=[], + campaign_id='', ): """ Sends the message via Braze Rest API /messages/send @@ -306,6 +307,7 @@ def send_message( # pylint: disable=dangerous-default-value sender_alias (str): sender alias for email e.g. edX Support Team reply_to (str): Enterprise Customer reply to address for email reply attachments (list): list of dicts with filename and url keys + campaign_id (str): The id of the campaign this email is associated with Request message format: Content-Type: application/json @@ -313,6 +315,7 @@ def send_message( # pylint: disable=dangerous-default-value Body: { "external_user_ids": [ "user1@example.com", "user2@example.org" ], + "campaign_id": "some-campaign-identifier", "messages": { "email": { "app_id": "99999999-9999-9999-9999-999999999999", @@ -366,6 +369,7 @@ def send_message( # pylint: disable=dangerous-default-value message = { 'user_aliases': user_aliases, 'external_user_ids': external_ids, + 'campaign_id': campaign_id, 'recipient_subscription_state': 'all', 'messages': { 'email': email diff --git a/ecommerce_worker/email/v1/braze/tasks.py b/ecommerce_worker/email/v1/braze/tasks.py index 609e41ac..06fa1ba2 100644 --- a/ecommerce_worker/email/v1/braze/tasks.py +++ b/ecommerce_worker/email/v1/braze/tasks.py @@ -12,7 +12,7 @@ def send_offer_assignment_email_via_braze(self, user_email, offer_assignment_id, subject, email_body, sender_alias, - reply_to, attachments, site_code): # pylint: disable=invalid-name + reply_to, attachments, site_code): """ Sends the offer assignment email via Braze. @@ -31,13 +31,15 @@ def send_offer_assignment_email_via_braze(self, user_email, offer_assignment_id, try: user_emails = [user_email] braze_client = get_braze_client(site_code) - response = braze_client.send_message( + response = _send_braze_message( + braze_client, email_ids=user_emails, subject=subject, body=email_body, sender_alias=sender_alias, reply_to=reply_to, - attachments=attachments + attachments=attachments, + campaign_id=config.get('ENTERPRISE_CODE_ASSIGNMENT_CAMPAIGN_ID'), ) if response and response['success']: dispatch_id = response['dispatch_id'] @@ -81,13 +83,15 @@ def send_offer_update_email_via_braze(self, user_email, subject, email_body, sen try: user_emails = [user_email] braze_client = get_braze_client(site_code) - braze_client.send_message( + _send_braze_message( + braze_client, email_ids=user_emails, subject=subject, body=email_body, sender_alias=sender_alias, reply_to=reply_to, - attachments=attachments + attachments=attachments, + campaign_id=config.get('ENTERPRISE_CODE_UPDATE_CAMPAIGN_ID'), ) except (BrazeRateLimitError, BrazeInternalServerError) as exc: raise self.retry(countdown=config.get('BRAZE_RETRY_SECONDS'), @@ -116,12 +120,14 @@ def send_offer_usage_email_via_braze(self, emails, subject, email_body, reply_to try: user_emails = list(emails.strip().split(",")) braze_client = get_braze_client(site_code) - braze_client.send_message( + _send_braze_message( + braze_client, email_ids=user_emails, subject=subject, body=email_body, reply_to=reply_to, - attachments=attachments + attachments=attachments, + campaign_id=config.get('ENTERPRISE_CODE_USAGE_CAMPAIGN_ID'), ) except (BrazeRateLimitError, BrazeInternalServerError) as exc: raise self.retry(countdown=config.get('BRAZE_RETRY_SECONDS'), @@ -152,13 +158,15 @@ def send_code_assignment_nudge_email_via_braze(self, email, subject, email_body, try: user_emails = [email] braze_client = get_braze_client(site_code) - braze_client.send_message( + _send_braze_message( + braze_client, email_ids=user_emails, subject=subject, body=email_body, sender_alias=sender_alias, reply_to=reply_to, attachments=attachments, + campaign_id=config.get('ENTERPRISE_CODE_NUDGE_CAMPAIGN_ID'), ) except (BrazeRateLimitError, BrazeInternalServerError) as exc: raise self.retry(countdown=config.get('BRAZE_RETRY_SECONDS'), @@ -168,3 +176,13 @@ def send_code_assignment_nudge_email_via_braze(self, email, subject, email_body, '[Code Assignment Nudge Email] Error in offer nudge notification with message --- ' '{message}'.format(message=email_body) ) + + +def _send_braze_message(braze_client, **kwargs): + """ + Helper to send braze messages. Pops any falsey `campaign_id` + argument before sending. + """ + if 'campaign_id' in kwargs and not kwargs['campaign_id']: + kwargs.pop('campaign_id') + return braze_client.send_message(**kwargs) diff --git a/ecommerce_worker/email/v1/braze/tests/test_tasks.py b/ecommerce_worker/email/v1/braze/tests/test_tasks.py index 8b99c093..470059af 100644 --- a/ecommerce_worker/email/v1/braze/tests/test_tasks.py +++ b/ecommerce_worker/email/v1/braze/tests/test_tasks.py @@ -50,6 +50,10 @@ class SendEmailsViaBrazeTests(TestCase): 'EXPORT_ID_ENDPOINT': '/users/export/ids', 'CAMPAIGN_SEND_ENDPOINT': '/campaigns/trigger/send', 'ENTERPRISE_CAMPAIGN_ID': '', + 'ENTERPRISE_CODE_ASSIGNMENT_CAMPAIGN_ID': 'the-code-assignment-campaign-id', + 'ENTERPRISE_CODE_UPDATE_CAMPAIGN_ID': 'the-code-update-campaign-id', + 'ENTERPRISE_CODE_USAGE_CAMPAIGN_ID': 'the-code-usage-campaign-id', + 'ENTERPRISE_CODE_NUDGE_CAMPAIGN_ID': '', # cover case where a `campaign_id` kwarg is falsey. 'FROM_EMAIL': '', 'BRAZE_RETRY_SECONDS': 3600, 'BRAZE_RETRY_ATTEMPTS': 6, diff --git a/setup.py b/setup.py index a5476ef2..ac4fae50 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def is_requirement(line): setup( name='edx-ecommerce-worker', - version='3.0.0', + version='3.1.0', description='Celery tasks supporting the operations of edX\'s ecommerce service', long_description=long_description, classifiers=[