diff --git a/customerio/__init__.py b/customerio/__init__.py index ee707cb..f7dda1c 100644 --- a/customerio/__init__.py +++ b/customerio/__init__.py @@ -2,5 +2,5 @@ from customerio.client_base import CustomerIOException from customerio.track import CustomerIO -from customerio.api import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest +from customerio.api import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest, SendInboxMessageRequest from customerio.regions import Regions diff --git a/customerio/api.py b/customerio/api.py index e2ba140..3474fb9 100644 --- a/customerio/api.py +++ b/customerio/api.py @@ -34,6 +34,12 @@ def send_sms(self, request): resp = self.send_request('POST', self.url + "/v1/send/sms", request) return json.loads(resp) + def send_inbox_message(self, request): + if isinstance(request, SendInboxMessageRequest): + request = request._to_dict() + resp = self.send_request('POST', self.url + "/v1/send/inbox_message", request) + return json.loads(resp) + # builds the session. def _build_session(self): session = super()._build_session() @@ -219,7 +225,7 @@ def _to_dict(self): return data class SendSMSRequest(object): - '''An object with all the options avaiable for triggering a transactional push message''' + '''An object with all the options avaiable for triggering a transactional SMS message''' def __init__(self, transactional_message_id=None, to=None, @@ -264,3 +270,44 @@ def _to_dict(self): data[name] = value return data + +class SendInboxMessageRequest(object): + '''An object with all the options avaiable for triggering a transactional inbox message''' + def __init__(self, + transactional_message_id=None, + identifiers=None, + disable_message_retention=None, + queue_draft=None, + message_data=None, + send_at=None, + language=None, + ): + + self.transactional_message_id = transactional_message_id + self.identifiers = identifiers + self.disable_message_retention = disable_message_retention + self.queue_draft = queue_draft + self.message_data = message_data + self.send_at = send_at + self.language = language + + def _to_dict(self): + '''Build a request payload from the object''' + field_map = dict( + # field name is the same as the payload field name + transactional_message_id="transactional_message_id", + identifiers="identifiers", + disable_message_retention="disable_message_retention", + queue_draft="queue_draft", + message_data="message_data", + send_at="send_at", + language="language", + ) + + data = {} + for field, name in field_map.items(): + value = getattr(self, field, None) + if value is not None: + data[name] = value + + return data diff --git a/tests/server.py b/tests/server.py index 5fdf2cc..d815595 100644 --- a/tests/server.py +++ b/tests/server.py @@ -14,6 +14,15 @@ def create_ssl_context(): """Create SSL context for Python 3.12+ compatibility""" context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.minimum_version = ssl.TLSVersion.TLSv1_2 + # Disable hostname and certificate verification for self-signed certs + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + # Allow weaker ciphers for test compatibility + try: + context.set_ciphers('DEFAULT@SECLEVEL=1') + except ssl.SSLError: + # Fall back if the cipher string is not supported + pass return context request_counts = dict() @@ -28,12 +37,16 @@ class Handler(BaseHTTPRequestHandler): ''' def do_DELETE(self): self.send_response(200) + self.send_header('Content-Length', '0') self.end_headers() def do_POST(self): + response_body = bytes("{}", "utf-8") self.send_response(200) + self.send_header('Content-Type', 'application/json') + self.send_header('Content-Length', str(len(response_body))) self.end_headers() - self.wfile.write(bytes("{}", "utf-8")) + self.wfile.write(response_body) def do_PUT(self): global request_counts @@ -49,6 +62,7 @@ def do_PUT(self): if processed > fail_count: # return a valid response self.send_response(200) + self.send_header('Content-Length', '0') self.end_headers() return diff --git a/tests/test_api.py b/tests/test_api.py index 2bd7903..ea68a55 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -5,7 +5,7 @@ import sys import unittest -from customerio import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest, Regions, CustomerIOException +from customerio import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest, SendInboxMessageRequest, Regions, CustomerIOException from customerio.__version__ import __version__ as ClientVersion from tests.server import HTTPSTestCase @@ -111,5 +111,21 @@ def test_send_sms(self): self.client.send_sms(sms) + def test_send_inbox_message(self): + self.client.http.hooks = dict(response=partial(self._check_request, rq={ + 'method': 'POST', + 'authorization': "Bearer app_api_key", + 'content_type': 'application/json', + 'url_suffix': '/v1/send/inbox_message', + 'body': {"identifiers": {"id":"customer_1"}, "transactional_message_id": 100} + })) + + inbox_message = SendInboxMessageRequest( + identifiers={"id":"customer_1"}, + transactional_message_id=100, + ) + + self.client.send_inbox_message(inbox_message) + if __name__ == '__main__': unittest.main()