From f9ef54fe5a72095924524f6befebdd302034e935 Mon Sep 17 00:00:00 2001 From: mark floyd Date: Wed, 20 Mar 2019 19:18:44 -0700 Subject: [PATCH] [DROID-1657] New endpoints for API triggered campaigns, minor style fixes --- braze/client.py | 79 +++++++++++++++++++++++++++++++++++--- tests/braze/test_client.py | 55 ++++++++++++++++++++++++-- 2 files changed, 124 insertions(+), 10 deletions(-) diff --git a/braze/client.py b/braze/client.py index c6aeb42..c37dd4d 100644 --- a/braze/client.py +++ b/braze/client.py @@ -10,9 +10,13 @@ USER_DELETE_ENDPOINT = "/users/delete" USER_EXPORT_ENDPOINT = "/users/export/ids" #: Endpoint for immediate send of Push Notifications -MESSAGE_SEND_NOW = "/messages/send" +MESSAGE_SEND = "/messages/send" #: Endpoint for scheduled send of Push Notifications -MESSAGE_SEND_SCHEDULED = "/messages/schedule/create" +MESSAGE_SCHEDULE_CREATE = "/messages/schedule/create" +#: Endpoint for Trigger Campaign Sends +CAMPAIGN_TRIGGER_SEND = "/campaigns/trigger/send" +#: Endpoint for Scheduled Trigger Campaign Sends +CAMPAIGN_TRIGGER_SCHEDULE_CREATE = "/campaigns/trigger/schedule/create" MAX_RETRIES = 3 # Max time to wait between API call retries MAX_WAIT_SECONDS = 1.25 @@ -258,9 +262,9 @@ def message_send( :param send_id: :param override_frequency_capping: :param recipient_subscription_state: - :return: + :return: json dict response, for example: {"message": "success", "errors": [], "client_error": ""} """ - self.request_url = self.api_url + MESSAGE_SEND_NOW + self.request_url = self.api_url + MESSAGE_SEND payload = {"messages": messages} @@ -313,9 +317,9 @@ def message_schedule_create( :param send_id: :param override_messaging_limits: :param recipient_subscription_state: - :return: + :return: json dict response, for example: {"message": "success", "errors": [], "client_error": ""} """ - self.request_url = self.api_url + MESSAGE_SEND_SCHEDULED + self.request_url = self.api_url + MESSAGE_SCHEDULE_CREATE payload = {"messages": messages, "schedule": schedule} @@ -339,3 +343,66 @@ def message_schedule_create( payload["recipient_subscription_state"] = recipient_subscription_state return self.__create_request(payload) + + def campaign_trigger_send( + self, campaign_id, send_id=None, broadcast=None, audience=None, recipients=None + ): + """ + Send Messages via API Triggered Delivery + ref: https://www.braze.com/docs/developer_guide/rest_api/messaging/#sending-messages-via-api-triggered-delivery + :param campaign_id: + :param send_id: + :param broadcast: + :param audience: + :param recipients: + :return: json dict response, for example: {"message": "success", "errors": [], "client_error": ""} + """ + self.request_url = self.api_url + CAMPAIGN_TRIGGER_SEND + + payload = {"campaign_id": campaign_id} + + if send_id is not None: + payload["send_id"] = send_id + if broadcast is not None: + payload["broadcast"] = broadcast + if audience is not None: + payload["audience"] = audience + if recipients is not None: + payload["recipients"] = recipients + + return self.__create_request(payload) + + def campaign_trigger_schedule_create( + self, + campaign_id, + schedule, + send_id=None, + broadcast=None, + audience=None, + recipients=None, + ): + """ + Send Messages via API Triggered Delivery at a specified time + ref: https://www.braze.com/docs/developer_guide/rest_api/messaging/#schedule-endpoints + :param campaign_id: + :param schedule: + :param send_id: + :param broadcast: + :param audience: + :param recipients: + :return: json dict response, for example: {"message": "success", "errors": [], "client_error": ""} + """ + self.request_url = self.api_url + CAMPAIGN_TRIGGER_SCHEDULE_CREATE + + payload = {"campaign_id": campaign_id, "schedule": schedule} + + if send_id is not None: + payload["send_id"] = send_id + if broadcast is not None: + payload["broadcast"] = broadcast + if audience is not None: + payload["audience"] = audience + if recipients is not None: + payload["recipients"] = recipients + + return self.__create_request(payload) diff --git a/tests/braze/test_client.py b/tests/braze/test_client.py index 2fc1c8b..074706a 100644 --- a/tests/braze/test_client.py +++ b/tests/braze/test_client.py @@ -1,15 +1,18 @@ from datetime import datetime import time +from uuid import uuid4 from braze.client import _wait_random_exp_or_rate_limit from braze.client import BrazeClient from braze.client import BrazeClientError from braze.client import BrazeInternalServerError from braze.client import BrazeRateLimitError +from braze.client import CAMPAIGN_TRIGGER_SCHEDULE_CREATE +from braze.client import CAMPAIGN_TRIGGER_SEND from braze.client import MAX_RETRIES from braze.client import MAX_WAIT_SECONDS -from braze.client import MESSAGE_SEND_NOW -from braze.client import MESSAGE_SEND_SCHEDULED +from braze.client import MESSAGE_SCHEDULE_CREATE +from braze.client import MESSAGE_SEND from freezegun import freeze_time import pytest from pytest import approx @@ -233,7 +236,7 @@ def test_standard_case(self, braze_client, requests_mock, messages): response = braze_client.message_send( messages, external_user_ids=external_user_ids ) - expected_url = braze_client.api_url + MESSAGE_SEND_NOW + expected_url = braze_client.api_url + MESSAGE_SEND assert expected_url == braze_client.request_url assert response["status_code"] == 201 assert response["message"] == "success" @@ -250,7 +253,51 @@ def test_standard_case(self, braze_client, requests_mock, messages): response = braze_client.message_schedule_create( messages, external_user_ids=external_user_ids, schedule=schedule ) - expected_url = braze_client.api_url + MESSAGE_SEND_SCHEDULED + expected_url = braze_client.api_url + MESSAGE_SCHEDULE_CREATE + assert expected_url == braze_client.request_url + assert response["status_code"] == 201 + assert response["message"] == "success" + + class TestTriggeredAPICampaign(object): + @pytest.fixture + def trigger_props(self): + return {"key_1": "value_1", "key_2": "value_2"} + + class TestCampaignTriggerSend(object): + def test_standard_case(self, braze_client, requests_mock, trigger_props): + campaign_id = str(uuid4()) + recipients = [ + {"external_user_id": 1, "trigger_properties": trigger_props} + ] + headers = {"Content-Type": "application/json"} + mock_json = {"message": "success"} + requests_mock.post( + ANY, json=mock_json, status_code=201, headers=headers + ) + response = braze_client.campaign_trigger_send( + campaign_id, recipients=recipients + ) + expected_url = braze_client.api_url + CAMPAIGN_TRIGGER_SEND + assert expected_url == braze_client.request_url + assert response["status_code"] == 201 + assert response["message"] == "success" + + class TestCampaignTriggerScheduleCreate(object): + def test_standard_case(self, braze_client, requests_mock, trigger_props): + campaign_id = str(uuid4()) + recipients = [ + {"external_user_id": 1, "trigger_properties": trigger_props} + ] + headers = {"Content-Type": "application/json"} + schedule = {"time": datetime.now().isoformat()} + mock_json = {"message": "success"} + requests_mock.post( + ANY, json=mock_json, status_code=201, headers=headers + ) + response = braze_client.campaign_trigger_schedule_create( + campaign_id, schedule, recipients=recipients + ) + expected_url = braze_client.api_url + CAMPAIGN_TRIGGER_SCHEDULE_CREATE assert expected_url == braze_client.request_url assert response["status_code"] == 201 assert response["message"] == "success"