This repository has been archived by the owner on Nov 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated Braze client for non edx users
- Loading branch information
1 parent
295b1a6
commit fc8d5ab
Showing
7 changed files
with
191 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
|
||
import requests | ||
|
||
from urllib.parse import urlencode | ||
from urllib.parse import urlencode, urljoin | ||
|
||
from celery.utils.log import get_task_logger | ||
|
||
|
@@ -33,13 +33,12 @@ def get_braze_configuration(site_code): | |
return config | ||
|
||
|
||
def get_braze_client(site_code, endpoint=None): | ||
def get_braze_client(site_code): | ||
""" | ||
Returns a Braze client for the specified site. | ||
Arguments: | ||
site_code (str): Site for which the client should be configured. | ||
endpoint (str): The endpoint for the API e.g. /messages/send or /email/hard_bounces | ||
Returns: | ||
BrazeClient | ||
|
@@ -60,25 +59,31 @@ def get_braze_client(site_code, endpoint=None): | |
rest_api_key = config.get('BRAZE_REST_API_KEY') | ||
webapp_api_key = config.get('BRAZE_WEBAPP_API_KEY') | ||
rest_api_url = config.get('REST_API_URL') | ||
message_endpoint = endpoint or config.get('MESSAGES_SEND_ENDPOINT') | ||
messages_send_endpoint = config.get('MESSAGES_SEND_ENDPOINT') | ||
email_bounce_endpoint = config.get('EMAIL_BOUNCE_ENDPOINT') | ||
new_alias_endpoint = config.get('NEW_ALIAS_ENDPOINT') | ||
users_track_endpoint = config.get('USERS_TRACK_ENDPOINT') | ||
from_email = config.get('FROM_EMAIL') | ||
email_template_id = config.get('EMAIL_TEMPLATE_ID') | ||
|
||
if ( | ||
not rest_api_key or | ||
not webapp_api_key or | ||
not rest_api_url or | ||
not message_endpoint or | ||
not from_email | ||
not webapp_api_key | ||
): | ||
msg = 'Required parameters missing for site {}'.format(site_code) | ||
msg = 'Required keys missing for site {}'.format(site_code) | ||
log.error(msg) | ||
raise ConfigurationError(msg) | ||
|
||
return BrazeClient( | ||
rest_api_key=rest_api_key, | ||
webapp_api_key=webapp_api_key, | ||
request_url=rest_api_url + message_endpoint, | ||
from_email=from_email | ||
rest_api_url=rest_api_url, | ||
messages_send_endpoint=messages_send_endpoint, | ||
email_bounce_endpoint=email_bounce_endpoint, | ||
new_alias_endpoint=new_alias_endpoint, | ||
users_track_endpoint=users_track_endpoint, | ||
from_email=from_email, | ||
email_template_id=email_template_id | ||
) | ||
|
||
|
||
|
@@ -87,34 +92,56 @@ class BrazeClient(object): | |
Client for Braze REST API | ||
""" | ||
|
||
def __init__(self, rest_api_key, webapp_api_key, request_url, from_email): | ||
def __init__( | ||
self, | ||
rest_api_key, | ||
webapp_api_key, | ||
rest_api_url, | ||
messages_send_endpoint, | ||
email_bounce_endpoint, | ||
new_alias_endpoint, | ||
users_track_endpoint, | ||
from_email, | ||
email_template_id | ||
): | ||
""" | ||
Initialize the Braze Client with configuration values. | ||
Arguments: | ||
rest_api_key (str): API key to use for accessing Braze REST endpoints | ||
webapp_api_key (str): Key that identifies the Braze webapp application | ||
request_url (str): Braze endpoint url | ||
rest_api_url (str): REST API url, | ||
messages_send_endpoint (str): Messages send endpoint, | ||
email_bounce_endpoint (str): Email bounce endpoint, | ||
new_alias_endpoint (str): New alias endpoint, | ||
users_track_endpoint (str): Users track endpoint, | ||
from_email (str): Braze email from address | ||
email_template_id (str): Braze email template identifier | ||
""" | ||
self.rest_api_key = rest_api_key | ||
self.webapp_api_key = webapp_api_key | ||
self.rest_api_url = rest_api_url | ||
self.messages_send_endpoint = messages_send_endpoint | ||
self.email_bounce_endpoint = email_bounce_endpoint | ||
self.new_alias_endpoint = new_alias_endpoint | ||
self.users_track_endpoint = users_track_endpoint | ||
self.from_email = from_email | ||
self.email_template_id = email_template_id | ||
self.session = requests.Session() | ||
self.request_url = request_url | ||
|
||
def __create_post_request(self, body): | ||
def __create_post_request(self, body, endpoint): | ||
""" | ||
Creates a request and returns a response. | ||
Arguments: | ||
body (dict): The request body | ||
endpoint (str): The endpoint for the API e.g. /messages/send or /email/hard_bounces | ||
Returns: | ||
response (dict): The response object | ||
""" | ||
response = {'errors': []} | ||
r = self._post_request(body) | ||
r = self._post_request(body, endpoint) | ||
response.update(r.json()) | ||
response['status_code'] = r.status_code | ||
|
||
|
@@ -126,39 +153,41 @@ def __create_post_request(self, body): | |
raise BrazeClientError(message, response['errors']) | ||
return response | ||
|
||
def _post_request(self, body): | ||
def _post_request(self, body, endpoint): | ||
""" | ||
Http posts the message body with associated headers. | ||
Arguments: | ||
body (dict): The request body | ||
endpoint (str): The endpoint for the API e.g. /messages/send or /email/hard_bounces | ||
Returns: | ||
r (requests.Response): The http response object | ||
""" | ||
self.session.headers.update( | ||
{'Authorization': u'Bearer {}'.format(self.rest_api_key), 'Content-Type': 'application/json'} | ||
) | ||
r = self.session.post(self.request_url, json=body, timeout=2) | ||
r = self.session.post(urljoin(self.rest_api_url, endpoint), json=body, timeout=2) | ||
if r.status_code == 429: | ||
reset_epoch_s = float(r.headers.get('X-RateLimit-Reset', 0)) | ||
raise BrazeRateLimitError(reset_epoch_s) | ||
elif str(r.status_code).startswith('5'): | ||
raise BrazeInternalServerError | ||
return r | ||
|
||
def __create_get_request(self, parameters): | ||
def __create_get_request(self, parameters, endpoint): | ||
""" | ||
Creates a request and returns a response. | ||
Arguments: | ||
parameters (dict): The request parameters | ||
endpoint (str): The endpoint for the API e.g. /messages/send or /email/hard_bounces | ||
Returns: | ||
response (dict): The response object | ||
""" | ||
response = {'errors': []} | ||
r = self._get_request(parameters) | ||
r = self._get_request(parameters, endpoint) | ||
response.update(r.json()) | ||
response['status_code'] = r.status_code | ||
message = response["message"] | ||
|
@@ -169,20 +198,21 @@ def __create_get_request(self, parameters): | |
raise BrazeClientError(message, response['errors']) | ||
return response | ||
|
||
def _get_request(self, parameters): | ||
def _get_request(self, parameters, endpoint): | ||
""" | ||
Http GET the parameters with associated headers. | ||
Arguments: | ||
parameters (dict): The request parameters | ||
endpoint (str): The endpoint for the API e.g. /messages/send or /email/hard_bounces | ||
Returns: | ||
r (requests.Response): The http response object | ||
""" | ||
self.session.headers.update( | ||
{'Authorization': u'Bearer {}'.format(self.rest_api_key), 'Content-Type': 'application/json'} | ||
) | ||
url_with_parameters = self.request_url + '?' + urlencode(parameters) | ||
url_with_parameters = urljoin(self.rest_api_url, endpoint) + '?' + urlencode(parameters) | ||
r = self.session.get(url_with_parameters) | ||
if r.status_code == 429: | ||
reset_epoch_s = float(r.headers.get('X-RateLimit-Reset', 0)) | ||
|
@@ -191,6 +221,56 @@ def _get_request(self, parameters): | |
raise BrazeInternalServerError | ||
return r | ||
|
||
def create_braze_alias(self, recipient_emails): | ||
""" | ||
Creates a Braze anonymous user and assigns it the recipient email address. | ||
Alias naming format: | ||
{ | ||
"attributes": [ | ||
{ | ||
"user_alias" : { | ||
"alias_name" : "Enterprise", | ||
"alias_label" : "[email protected]" | ||
}, | ||
"email" : "[email protected]" | ||
} | ||
] | ||
} | ||
Arguments: | ||
recipient_emails (list): e.g. ['[email protected]', '[email protected]'] | ||
""" | ||
if not recipient_emails: | ||
raise BrazeClientError("Missing parameters for Alias creation") | ||
user_aliases = [] | ||
attributes = [] | ||
for recipient_email in recipient_emails: | ||
user_alias = { | ||
'alias_name': 'Enterprise', | ||
'alias_label': recipient_email | ||
} | ||
user_aliases.append(user_alias) | ||
attribute = { | ||
'user_alias': { | ||
'alias_name': 'Enterprise', | ||
'alias_label': recipient_email | ||
}, | ||
'email': recipient_email | ||
} | ||
attributes.append(attribute) | ||
|
||
alias_message = { | ||
'user_aliases': user_aliases, | ||
} | ||
self.__create_post_request(alias_message, self.new_alias_endpoint) | ||
|
||
attribute_message = { | ||
'attributes': attributes | ||
} | ||
self.__create_post_request(attribute_message, self.users_track_endpoint) | ||
|
||
def send_message( | ||
self, | ||
email_ids, | ||
|
@@ -232,20 +312,29 @@ def send_message( | |
""" | ||
if not email_ids or not subject or not body: | ||
raise BrazeClientError("Missing parameters for Braze email") | ||
self.create_braze_alias(email_ids) | ||
user_aliases = [] | ||
for email_id in email_ids: | ||
user_alias = { | ||
'alias_name': 'Enterprise', | ||
'alias_label': email_id | ||
} | ||
user_aliases.append(user_alias) | ||
email = { | ||
'app_id': self.webapp_api_key, | ||
'subject': subject, | ||
'from': sender_alias + self.from_email, | ||
'body': body | ||
'body': body, | ||
'email_template_id': self.email_template_id | ||
} | ||
message = { | ||
'external_user_ids': email_ids, | ||
'user_aliases': user_aliases, | ||
'messages': { | ||
'email': email | ||
} | ||
} | ||
|
||
return self.__create_post_request(message) | ||
return self.__create_post_request(message, self.messages_send_endpoint) | ||
|
||
def did_email_bounce( | ||
self, | ||
|
@@ -266,7 +355,7 @@ def did_email_bounce( | |
'email': email_id | ||
} | ||
|
||
response = self.__create_get_request(parameters) | ||
response = self.__create_get_request(parameters, self.email_bounce_endpoint) | ||
if response['emails']: | ||
return True | ||
|
||
|
Oops, something went wrong.