Skip to content

Commit

Permalink
Merge pull request #13 from edx/shahbaz/VAN-1273
Browse files Browse the repository at this point in the history
feat: add method to unsubscribe user email
  • Loading branch information
macdiesel authored Mar 1, 2023
2 parents 6918d5e + ccc6ba0 commit fc3a277
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Change Log
Unreleased
~~~~~~~~~~

[0.1.6]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
feat: add unsubscribe_user_email method

[0.1.5]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
feat: add send_canvas_message method
Expand Down
2 changes: 1 addition & 1 deletion braze/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Python client for interacting with Braze APIs.
"""

__version__ = '0.1.5'
__version__ = '0.1.6'
37 changes: 36 additions & 1 deletion braze/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@

import requests

from braze.constants import TRACK_USER_COMPONENT_CHUNK_SIZE, USER_ALIAS_CHUNK_SIZE, BrazeAPIEndpoints
from braze.constants import (
TRACK_USER_COMPONENT_CHUNK_SIZE,
UNSUBSCRIBED_STATE,
USER_ALIAS_CHUNK_SIZE,
BrazeAPIEndpoints,
)

from .exceptions import (
BrazeBadRequestError,
Expand Down Expand Up @@ -400,3 +405,33 @@ def send_canvas_message(
}

return self._post_request(message, BrazeAPIEndpoints.SEND_CANVAS)

def unsubscribe_user_email(
self,
email
):
"""
Unsubscribe user's email via API.
https://www.braze.com/docs/api/endpoints/email/post_email_subscription_status/
Arguments:
email (str, list): The maximum number of emails in a list can be 50 or just one str
e.g. 'test1@example.com' or ['test2@example.com', 'test3@example.com', ...]
Returns:
response (dict): The response object
"""
if not email:
msg = 'Bad arguments, please check that emails are non-empty.'
raise BrazeClientError(msg)

if isinstance(email, list) and len(email) > 50:
msg = 'Bad arguments, The maximum number of emails in a list can be 50.'
raise BrazeClientError(msg)

payload = {
'email': email,
'subscription_state': UNSUBSCRIBED_STATE
}

return self._post_request(payload, BrazeAPIEndpoints.UNSUBSCRIBE_USER_EMAIL)
2 changes: 2 additions & 0 deletions braze/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ class BrazeAPIEndpoints:
NEW_ALIAS = '/users/alias/new'
TRACK_USER = '/users/track'
IDENTIFY_USERS = '/users/identify'
UNSUBSCRIBE_USER_EMAIL = '/email/status'


# Braze enforced request size limits
TRACK_USER_COMPONENT_CHUNK_SIZE = 75
USER_ALIAS_CHUNK_SIZE = 50
UNSUBSCRIBED_STATE = 'unsubscribed'
36 changes: 36 additions & 0 deletions tests/braze/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class BrazeClientTests(TestCase):
NEW_ALIAS_URL = BRAZE_URL + BrazeAPIEndpoints.NEW_ALIAS
USERS_IDENTIFY_URL = BRAZE_URL + BrazeAPIEndpoints.IDENTIFY_USERS
USERS_TRACK_URL = BRAZE_URL + BrazeAPIEndpoints.TRACK_USER
UNSUBSCRIBE_USER_EMAIL_URL = BRAZE_URL + BrazeAPIEndpoints.UNSUBSCRIBE_USER_EMAIL

def _get_braze_client(self):
return BrazeClient(
Expand Down Expand Up @@ -566,3 +567,38 @@ def test_braze_internal_server_error(self):
with self.assertRaises(BrazeInternalServerError):
client = self._get_braze_client()
client.get_braze_external_id(email='test@example.com')

def test_unsubscribe_user_email_bad_args_empty_email(self):
"""
Tests that arguments are validated.
"""
client = self._get_braze_client()
with self.assertRaises(BrazeClientError):
client.unsubscribe_user_email(email=[])

def test_unsubscribe_user_email_bad_args_long_email_length(self):
"""
Tests that arguments are validated.
"""
emails = ['test@example.com'] * 51
client = self._get_braze_client()
with self.assertRaises(BrazeClientError):
client.unsubscribe_user_email(email=emails)

@responses.activate
def test_unsubscribe_user_email_success(self):
"""
Tests a successful call to the /email/status endpoint.
"""
responses.add(
responses.POST,
self.UNSUBSCRIBE_USER_EMAIL_URL,
json={'message': 'success'},
status=201
)
client = self._get_braze_client()
response = client.unsubscribe_user_email(email='test@example.com')

self.assertEqual(response, {'message': 'success'})
assert len(responses.calls) == 1
assert responses.calls[0].request.url == self.UNSUBSCRIBE_USER_EMAIL_URL

0 comments on commit fc3a277

Please sign in to comment.