From 15a03f7bcac5f11c708ca2bc22acbf130937d19d Mon Sep 17 00:00:00 2001 From: ElliottStorey Date: Thu, 3 Aug 2023 21:54:19 -0500 Subject: [PATCH 1/5] Added get, post, and delete contact endpoints --- sendblue/sendblue.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/sendblue/sendblue.py b/sendblue/sendblue.py index d72447c..eeabeed 100644 --- a/sendblue/sendblue.py +++ b/sendblue/sendblue.py @@ -4,9 +4,9 @@ class Sendblue: def __init__(self, api_key: str, api_secret: str) -> None: self.api_key = api_key self.api_secret = api_secret - self.base_url = 'https://api.sendblue.co/api' + self.base_url = 'https://api.sendblue.co' - def request(self, endpoint: str, data: dict = None) -> dict: + def request(self, endpoint: str, method: str, data: dict = None) -> dict: url = self.base_url + endpoint headers = { 'sb-api-key-id': self.api_key, @@ -14,10 +14,14 @@ def request(self, endpoint: str, data: dict = None) -> dict: 'Content-Type': 'application/json' } - if data: + if method == 'get': + response = requests.get(url, headers=headers, json=data) + elif method == 'post': response = requests.post(url, headers=headers, json=data) - else: - response = requests.get(url, headers=headers) + elif method == 'put': + response = requests.put(url, headers=headers, json=data) + elif method == 'delete': + response = requests.delete(url, headers=headers, json=data) if not response.ok: raise Exception("Error: " + response.text) @@ -32,7 +36,7 @@ def send_message(self, number: str, content: str, send_style: str = None, media_ 'media_url': media_url, 'status_callback': status_callback } - return self.request('/send-message', data) + return self.request('/api/send-message', 'post', data) def send_group_message(self, numbers: list[str], content: str, group_id: str = None, send_style: str = None, media_url: str = None, status_callback: str = None): data = { @@ -43,7 +47,7 @@ def send_group_message(self, numbers: list[str], content: str, group_id: str = N 'media_url': media_url, 'status_callback': status_callback } - return self.request('/send-group-message', data) + return self.request('/api/send-group-message', 'post', data) def modify_group(self, group_id: str, modify_type: str, number: str): data = { @@ -51,13 +55,28 @@ def modify_group(self, group_id: str, modify_type: str, number: str): "modify_type": modify_type, "number": number } - return self.request('/modify-group', data) + return self.request('/modify-group', 'post', data) def lookup(self, number: str): - return self.request(f'/evaluate-service?number={number}') + return self.request(f'/api/evaluate-service?number={number}', 'get') def send_typing_indicator(self, number: str): data = { 'number': number } - return self.request(f'/send-typing-indicator?number={number}', data) + return self.request(f'/api/send-typing-indicator?number={number}', 'post', data) + + def get_contacts(self): + return self.request('/accounts/contacts', 'get') + + def create_contact(self, number: str, first_name: str = None, last_name: str = None, company_name: str = None): + data = { + 'number': number, + 'first_name': first_name, + 'last_name': last_name, + 'company_name': company_name + } + return self.request(f'/accounts/contacts', 'post', data) + + def delete_contact(self, contact_id: str): + return self.request(f'/accounts/contacts/{contact_id}') \ No newline at end of file From 6b5180573838991bfe090d659481387c15a33b52 Mon Sep 17 00:00:00 2001 From: ElliottStorey Date: Fri, 4 Aug 2023 15:32:03 -0500 Subject: [PATCH 2/5] Finished contact endpoints; removed request function; added session requests --- sendblue/__init__.py | 2 +- sendblue/sendblue.py | 82 ++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/sendblue/__init__.py b/sendblue/__init__.py index b6d63bc..ffc14e6 100644 --- a/sendblue/__init__.py +++ b/sendblue/__init__.py @@ -1 +1 @@ -from .sendblue import Sendblue +from .sendblue import Sendblue \ No newline at end of file diff --git a/sendblue/sendblue.py b/sendblue/sendblue.py index eeabeed..3220d01 100644 --- a/sendblue/sendblue.py +++ b/sendblue/sendblue.py @@ -2,32 +2,14 @@ class Sendblue: def __init__(self, api_key: str, api_secret: str) -> None: - self.api_key = api_key - self.api_secret = api_secret self.base_url = 'https://api.sendblue.co' - - def request(self, endpoint: str, method: str, data: dict = None) -> dict: - url = self.base_url + endpoint - headers = { - 'sb-api-key-id': self.api_key, - 'sb-api-secret-key': self.api_secret, + self.session = requests.Session() + self.session.headers = { + 'sb-api-key-id': api_key, + 'sb-api-secret-key': api_secret, 'Content-Type': 'application/json' } - if method == 'get': - response = requests.get(url, headers=headers, json=data) - elif method == 'post': - response = requests.post(url, headers=headers, json=data) - elif method == 'put': - response = requests.put(url, headers=headers, json=data) - elif method == 'delete': - response = requests.delete(url, headers=headers, json=data) - - if not response.ok: - raise Exception("Error: " + response.text) - - return response.json() - def send_message(self, number: str, content: str, send_style: str = None, media_url: str = None, status_callback: str = None): data = { 'number': number, @@ -36,7 +18,12 @@ def send_message(self, number: str, content: str, send_style: str = None, media_ 'media_url': media_url, 'status_callback': status_callback } - return self.request('/api/send-message', 'post', data) + url = self.base_url + '/api/send-message' + response = self.session.post(url, data) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def send_group_message(self, numbers: list[str], content: str, group_id: str = None, send_style: str = None, media_url: str = None, status_callback: str = None): data = { @@ -47,7 +34,12 @@ def send_group_message(self, numbers: list[str], content: str, group_id: str = N 'media_url': media_url, 'status_callback': status_callback } - return self.request('/api/send-group-message', 'post', data) + url = self.base_url + '/api/send-group-message' + response = self.session.post(url, data) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def modify_group(self, group_id: str, modify_type: str, number: str): data = { @@ -55,19 +47,39 @@ def modify_group(self, group_id: str, modify_type: str, number: str): "modify_type": modify_type, "number": number } - return self.request('/modify-group', 'post', data) + url = self.base_url + '/modify-group' + response = self.session.post(url, data) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def lookup(self, number: str): - return self.request(f'/api/evaluate-service?number={number}', 'get') + url = self.base_url + f'/api/evaluate-service?number={number}' + response = self.session.get(url) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def send_typing_indicator(self, number: str): data = { 'number': number } - return self.request(f'/api/send-typing-indicator?number={number}', 'post', data) + url = self.base_url + f'/api/send-typing-indicator?number={number}' + response = self.session.post(url, data) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def get_contacts(self): - return self.request('/accounts/contacts', 'get') + url = self.base_url + '/accounts/contacts' + response = self.session.get(url) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def create_contact(self, number: str, first_name: str = None, last_name: str = None, company_name: str = None): data = { @@ -76,7 +88,17 @@ def create_contact(self, number: str, first_name: str = None, last_name: str = N 'last_name': last_name, 'company_name': company_name } - return self.request(f'/accounts/contacts', 'post', data) + url = self.base_url + '/accounts/contacts' + response = self.session.post(url, data) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() def delete_contact(self, contact_id: str): - return self.request(f'/accounts/contacts/{contact_id}') \ No newline at end of file + url = self.base_url + '/accounts/contacts/{contact_id}' + response = self.session.delete(url) + if not response.ok: + raise Exception("Error: " + response.text) + else: + return response.json() \ No newline at end of file From bc0e9d138cf83f9e72ffec71ccfd11c68237503e Mon Sep 17 00:00:00 2001 From: ElliottStorey Date: Sat, 5 Aug 2023 13:46:00 -0500 Subject: [PATCH 3/5] Created a request function and added get message by message_id --- sendblue/sendblue.py | 74 ++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 51 deletions(-) diff --git a/sendblue/sendblue.py b/sendblue/sendblue.py index 3220d01..f0de265 100644 --- a/sendblue/sendblue.py +++ b/sendblue/sendblue.py @@ -9,6 +9,18 @@ def __init__(self, api_key: str, api_secret: str) -> None: 'sb-api-secret-key': api_secret, 'Content-Type': 'application/json' } + + def request(self, method: str, endpoint: str, data: dict = None): + url = self.base_url + endpoint + response = self.session.request(method, url, json=data) + try: + response.raise_for_status() + except requests.exceptions.HTTPError as e: + print(e, response.text) + return response.json() + + def get_message(self, message_id: str): + return self.request('get', f'/api/message/{message_id}') def send_message(self, number: str, content: str, send_style: str = None, media_url: str = None, status_callback: str = None): data = { @@ -18,12 +30,7 @@ def send_message(self, number: str, content: str, send_style: str = None, media_ 'media_url': media_url, 'status_callback': status_callback } - url = self.base_url + '/api/send-message' - response = self.session.post(url, data) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('post', '/api/send-message', data) def send_group_message(self, numbers: list[str], content: str, group_id: str = None, send_style: str = None, media_url: str = None, status_callback: str = None): data = { @@ -34,12 +41,7 @@ def send_group_message(self, numbers: list[str], content: str, group_id: str = N 'media_url': media_url, 'status_callback': status_callback } - url = self.base_url + '/api/send-group-message' - response = self.session.post(url, data) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('post', '/api/send-group-message', data) def modify_group(self, group_id: str, modify_type: str, number: str): data = { @@ -47,58 +49,28 @@ def modify_group(self, group_id: str, modify_type: str, number: str): "modify_type": modify_type, "number": number } - url = self.base_url + '/modify-group' - response = self.session.post(url, data) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('post', '/modify-group', data) def lookup(self, number: str): - url = self.base_url + f'/api/evaluate-service?number={number}' - response = self.session.get(url) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('get', f'/api/evaluate-service?number={number}') def send_typing_indicator(self, number: str): data = { 'number': number } - url = self.base_url + f'/api/send-typing-indicator?number={number}' - response = self.session.post(url, data) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('post', f'/api/send-typing-indicator?number={number}', data) def get_contacts(self): - url = self.base_url + '/accounts/contacts' - response = self.session.get(url) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('get', '/accounts/contacts') def create_contact(self, number: str, first_name: str = None, last_name: str = None, company_name: str = None): data = { 'number': number, - 'first_name': first_name, - 'last_name': last_name, - 'company_name': company_name + 'firstName': first_name, + 'lastName': last_name, + 'companyName': company_name } - url = self.base_url + '/accounts/contacts' - response = self.session.post(url, data) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() + return self.request('post', '/accounts/contacts', data) def delete_contact(self, contact_id: str): - url = self.base_url + '/accounts/contacts/{contact_id}' - response = self.session.delete(url) - if not response.ok: - raise Exception("Error: " + response.text) - else: - return response.json() \ No newline at end of file + return self.request('delete', f'/accounts/contacts/{contact_id}') \ No newline at end of file From 7dd49d7b182f016674a20be159754ba9cf49fec2 Mon Sep 17 00:00:00 2001 From: ElliottStorey Date: Mon, 7 Aug 2023 16:03:40 -0500 Subject: [PATCH 4/5] Added conversation thread support --- sendblue/sendblue.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sendblue/sendblue.py b/sendblue/sendblue.py index f0de265..74561c9 100644 --- a/sendblue/sendblue.py +++ b/sendblue/sendblue.py @@ -73,4 +73,7 @@ def create_contact(self, number: str, first_name: str = None, last_name: str = N return self.request('post', '/accounts/contacts', data) def delete_contact(self, contact_id: str): - return self.request('delete', f'/accounts/contacts/{contact_id}') \ No newline at end of file + return self.request('delete', f'/accounts/contacts/{contact_id}') + + def get_messages(self, contact_id: str): + return self.request('get', f'/accounts/messages?cid={contact_id}') \ No newline at end of file From a2a80a53cab3289280ccd25a0a450e85a857b099 Mon Sep 17 00:00:00 2001 From: ElliottStorey Date: Mon, 7 Aug 2023 16:46:53 -0500 Subject: [PATCH 5/5] Updated README --- README.md | 30 ++++++++++++++++++++++++++++++ sendblue/sendblue.py | 6 +++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 585b58e..dfc521d 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,12 @@ response = sendblue.send_message('+19998887777', 'Hello from Sendblue!', send_st response = sendblue.send_group_message(['+19998887777', '+19998887778'], 'Hello from Sendblue!', send_style='invisible', media_url='https://source.unsplash.com/random.png', status_callback='https://example.com/callback') ``` +### Get Message + +```python +response = sendblue.get_message('message_id') +``` + ### Modify Group ```python @@ -57,4 +63,28 @@ response = sendblue.lookup('+19998887777') ```python response = sendblue.send_typing_indicator('+19998887777') +``` + +### Get Contacts + +```python +response = sendblue.get_contacts() +``` + +### Create Contact + +```python +response = sendblue.create_contact('+19998887777', 'First Name', 'Last Name', 'Company Name') +``` + +### Delete Contact + +```python +response = sendblue.delete_contact('contact_id') +``` + +### Get Messages + +```python +response = sendblue.get_messages('contact_id') ``` \ No newline at end of file diff --git a/sendblue/sendblue.py b/sendblue/sendblue.py index 74561c9..c888cfb 100644 --- a/sendblue/sendblue.py +++ b/sendblue/sendblue.py @@ -18,9 +18,6 @@ def request(self, method: str, endpoint: str, data: dict = None): except requests.exceptions.HTTPError as e: print(e, response.text) return response.json() - - def get_message(self, message_id: str): - return self.request('get', f'/api/message/{message_id}') def send_message(self, number: str, content: str, send_style: str = None, media_url: str = None, status_callback: str = None): data = { @@ -43,6 +40,9 @@ def send_group_message(self, numbers: list[str], content: str, group_id: str = N } return self.request('post', '/api/send-group-message', data) + def get_message(self, message_id: str): + return self.request('get', f'/api/message/{message_id}') + def modify_group(self, group_id: str, modify_type: str, number: str): data = { "group_id": group_id,