Skip to content

Commit 1b0d779

Browse files
authored
Update messages api (#251)
* adding new viber channels * adding new viber message types and tests * adding tests for new viber action response * add sticker as a whatsapp channel, add specific errors to validation tests, increase max client_ref value * add new check for exclusive sticker dictionary keys
1 parent 4971eda commit 1b0d779

File tree

3 files changed

+290
-129
lines changed

3 files changed

+290
-129
lines changed

src/vonage/messages.py

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,32 @@
22

33
import re
44

5+
56
class Messages:
67
valid_message_channels = {'sms', 'mms', 'whatsapp', 'messenger', 'viber_service'}
78
valid_message_types = {
89
'sms': {'text'},
910
'mms': {'image', 'vcard', 'audio', 'video'},
10-
'whatsapp': {'text', 'image', 'audio', 'video', 'file', 'template', 'custom'},
11+
'whatsapp': {'text', 'image', 'audio', 'video', 'file', 'template', 'sticker', 'custom'},
1112
'messenger': {'text', 'image', 'audio', 'video', 'file'},
12-
'viber_service': {'text', 'image'}
13+
'viber_service': {'text', 'image', 'video', 'file'},
1314
}
14-
15+
1516
def __init__(self, client):
1617
self._client = client
1718
self._auth_type = 'jwt'
1819

19-
def send_message(self, params: dict):
20+
def send_message(self, params: dict):
2021
self.validate_send_message_input(params)
21-
22+
2223
if not hasattr(self._client, '_application_id'):
23-
self._auth_type='header'
24+
self._auth_type = 'header'
2425
return self._client.post(
25-
self._client.api_host(),
26+
self._client.api_host(),
2627
"/v1/messages",
27-
params,
28+
params,
2829
auth_type=self._auth_type,
29-
)
30+
)
3031

3132
def validate_send_message_input(self, params):
3233
self._check_input_is_dict(params)
@@ -36,24 +37,28 @@ def validate_send_message_input(self, params):
3637
self._check_valid_sender(params)
3738
self._channel_specific_checks(params)
3839
self._check_valid_client_ref(params)
39-
40+
4041
def _check_input_is_dict(self, params):
4142
if type(params) is not dict:
4243
raise MessagesError('Parameters to the send_message method must be specified as a dictionary.')
4344

4445
def _check_valid_message_channel(self, params):
4546
if params['channel'] not in Messages.valid_message_channels:
46-
raise MessagesError(f"""
47-
'{params['channel']}' is an invalid message channel.
47+
raise MessagesError(
48+
f"""
49+
"{params['channel']}" is an invalid message channel.
4850
Must be one of the following types: {self.valid_message_channels}'
49-
""")
51+
"""
52+
)
5053

5154
def _check_valid_message_type(self, params):
5255
if params['message_type'] not in self.valid_message_types[params['channel']]:
53-
raise MessagesError(f"""
56+
raise MessagesError(
57+
f"""
5458
"{params['message_type']}" is not a valid message type for channel "{params["channel"]}".
5559
Must be one of the following types: {self.valid_message_types[params["channel"]]}
56-
""")
60+
"""
61+
)
5762

5863
def _check_valid_recipient(self, params):
5964
if not isinstance(params['to'], str):
@@ -65,20 +70,29 @@ def _check_valid_recipient(self, params):
6570

6671
def _check_valid_sender(self, params):
6772
if not isinstance(params['from'], str) or params['from'] == "":
68-
raise MessagesError(f'Message sender ("frm={params["from"]}") set incorrectly. Set a valid name or number for the sender.')
73+
raise MessagesError(
74+
f'Message sender ("frm={params["from"]}") set incorrectly. Set a valid name or number for the sender.'
75+
)
6976

7077
def _channel_specific_checks(self, params):
71-
try:
72-
if params['channel'] == 'whatsapp' and params['message_type'] == 'template':
73-
params['whatsapp']
74-
if params['channel'] == 'viber_service':
75-
params['viber_service']
76-
except (KeyError, TypeError):
77-
raise MessagesError(f'''You must specify all required properties for message channel "{params["channel"]}".''')
78+
if (
79+
(params['channel'] == 'whatsapp' and params['message_type'] == 'template' and 'whatsapp' not in params)
80+
or (params['channel'] == 'whatsapp' and params['message_type'] == 'sticker' and 'sticker' not in params)
81+
or (params['channel'] == 'viber_service' and 'viber_service' not in params)
82+
):
83+
raise MessagesError(
84+
f'''You must specify all required properties for message channel "{params["channel"]}".'''
85+
)
86+
elif params['channel'] == 'whatsapp' and params['message_type'] == 'sticker':
87+
self._check_valid_whatsapp_sticker(params['sticker'])
7888

7989
def _check_valid_client_ref(self, params):
8090
if 'client_ref' in params:
81-
if len(params['client_ref']) <= 40:
91+
if len(params['client_ref']) <= 100:
8292
self._client_ref = params['client_ref']
8393
else:
84-
raise MessagesError('client_ref can be a maximum of 40 characters.')
94+
raise MessagesError('client_ref can be a maximum of 100 characters.')
95+
96+
def _check_valid_whatsapp_sticker(self, sticker):
97+
if ('id' not in sticker and 'url' not in sticker) or ('id' in sticker and 'url' in sticker):
98+
raise MessagesError('Must specify one, and only one, of "id" or "url" in the "sticker" field.')

tests/test_messages_send_message.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
from util import *
22

3+
34
@responses.activate
45
def test_send_sms_with_messages_api(messages, dummy_data):
56
stub(responses.POST, 'https://api.nexmo.com/v1/messages')
67

78
params = {
8-
'channel': 'sms',
9-
'message_type': 'text',
10-
'to': '447123456789',
9+
'channel': 'sms',
10+
'message_type': 'text',
11+
'to': '447123456789',
1112
'from': 'Vonage',
12-
'text': 'Hello from Vonage'
13+
'text': 'Hello from Vonage',
1314
}
1415

1516
assert isinstance(messages.send_message(params), dict)
@@ -18,21 +19,21 @@ def test_send_sms_with_messages_api(messages, dummy_data):
1819
assert b'"to": "447123456789"' in request_body()
1920
assert b'"text": "Hello from Vonage"' in request_body()
2021

22+
2123
@responses.activate
2224
def test_send_whatsapp_image_with_messages_api(messages, dummy_data):
2325
stub(responses.POST, 'https://api.nexmo.com/v1/messages')
2426

2527
params = {
26-
'channel': 'whatsapp',
27-
'message_type': 'image',
28-
'to': '447123456789',
28+
'channel': 'whatsapp',
29+
'message_type': 'image',
30+
'to': '447123456789',
2931
'from': '440123456789',
30-
'image': {'url': 'https://example.com/image.jpg', 'caption': 'fake test image'}
32+
'image': {'url': 'https://example.com/image.jpg', 'caption': 'fake test image'},
3133
}
3234

3335
assert isinstance(messages.send_message(params), dict)
3436
assert request_user_agent() == dummy_data.user_agent
3537
assert b'"from": "440123456789"' in request_body()
3638
assert b'"to": "447123456789"' in request_body()
3739
assert b'"image": {"url": "https://example.com/image.jpg", "caption": "fake test image"}' in request_body()
38-

0 commit comments

Comments
 (0)