diff --git a/.travis.yml b/.travis.yml index 2aebb87..0341517 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ python: install: - pip install mock==2.0 - pip install requests + - pip install . script: - python -m unittest discover -s tests/ -p test_*.py -v matrix: diff --git a/examples/mms.py b/examples/mms.py new file mode 100644 index 0000000..173a779 --- /dev/null +++ b/examples/mms.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +import messagebird + +ACCESS_KEY = os.environ.get('ACCESS_KEY', None) +if ACCESS_KEY is None: + print("Set environment ACCESS_KEY from https://dashboard.messagebird.com/en/developers/access") + exit(1) + +try: + # Create a MessageBird client with the specified ACCESS_KEY. + client = messagebird.Client(ACCESS_KEY) + # Send a MMS + mms = client.mms_create('Sarath','+4915238456487','Rich test message','https://www.messagebird.com/assets/images/og/messagebird.gif') + # Print the object information. + print("The following information was returned as a MMS object:\n%s" % mms) + +except messagebird.client.ErrorException as e: + print('\nAn error occured while requesting to send a MMS:\n') + for error in e.errors: + print(' code : %d' % error.code) + print(' description : %s' % error.description) + print(' parameter : %s\n' % error.parameter) \ No newline at end of file diff --git a/messagebird/base.py b/messagebird/base.py index ee88e8e..d6990a2 100644 --- a/messagebird/base.py +++ b/messagebird/base.py @@ -3,18 +3,20 @@ class Base(object): def load(self, data): for name, value in list(data.items()): - if hasattr(self, name): + if hasattr(self, name) and not callable(getattr(self,name)): setattr(self, name, value) return self - - def strip_nanoseconds_from_date(self, value): + + @staticmethod + def strip_nanoseconds_from_date(value): if str(value).find(".") != -1: return value[:-11] + value[-1:] return value - def value_to_time(self, value, format='%Y-%m-%dT%H:%M:%S+00:00'): - if value != None: - value = self.strip_nanoseconds_from_date(value) - return datetime.strptime(value, format) + @staticmethod + def value_to_time(value, format='%Y-%m-%dT%H:%M:%S+00:00'): + if value is not None: + value = Base.strip_nanoseconds_from_date(value) + return datetime.strptime(value, format) \ No newline at end of file diff --git a/messagebird/client.py b/messagebird/client.py index 5b8b9c8..43c286d 100644 --- a/messagebird/client.py +++ b/messagebird/client.py @@ -7,6 +7,7 @@ from messagebird.group import Group, GroupList from messagebird.hlr import HLR from messagebird.message import Message +from messagebird.mms import MMS from messagebird.voicemessage import VoiceMessage from messagebird.lookup import Lookup from messagebird.verify import Verify @@ -110,6 +111,31 @@ def message_delete(self, id): """Delete a message from the dashboard.""" self.request_plain_text('messages/' + str(id), 'DELETE') + def mms_create(self, originator, recipients, body, mediaUrls, subject = None, reference = None, scheduledDatetime = None): + ''' Send bulk mms. + + Args: + originator(str): name of the originator + recipients(str/list(str)): comma seperated numbers or list of numbers in E164 format + body(str) : text message body + mediaUrl(str) : list of URL's of attachments of the MMS message. + subject(str) : utf-encoded subject + reference(str) : client reference text + scheduledDatetime(str) : scheduled date time in RFC3339 format + Raises: + ErrorException: On api returning errors + + Returns: + MMS: On success an MMS instance instantiated with succcess response + ''' + if isinstance(recipients,list): + recipients = ','.join(recipients) + if isinstance(mediaUrls,str): + mediaUrls = [mediaUrls] + params = locals() + del(params['self']) + return MMS().load(self.request('mms', 'POST', params)) + def voice_message(self, id): "Retrieve the information of a specific voice message." return VoiceMessage().load(self.request('voicemessages/' + str(id))) @@ -250,6 +276,6 @@ def conversation_list_webhooks(self, limit=10, offset=0): def conversation_read_webhook(self, id): uri = CONVERSATION_WEB_HOOKS_PATH + '/' + str(id) return ConversationWebhook().load(self.request(uri, 'GET', None, CONVERSATION_TYPE)) - + def _format_query(self, limit, offset): return 'limit=' + str(limit) + '&offset=' + str(offset) diff --git a/messagebird/mms.py b/messagebird/mms.py new file mode 100644 index 0000000..39ffe97 --- /dev/null +++ b/messagebird/mms.py @@ -0,0 +1,56 @@ +from messagebird.base import Base +from messagebird.recipient import Recipient + +class MMS(Base): + def __init__(self): + self.id = None + self.href = None + self.direction = None + self.originator = None + self.subject = None + self.body = None + self.mediaUrls = None + self.reference = None + self._scheduledDatetime = None + self._createdDatetime = None + self._recipients = None + + @property + def scheduledDatetime(self): + return self._scheduledDatetime + + @scheduledDatetime.setter + def scheduledDatetime(self, value): + self._scheduledDatetime = self.value_to_time(value) + + @property + def createdDatetime(self): + return self._createdDatetime + + @createdDatetime.setter + def createdDatetime(self, value): + self._createdDatetime = self.value_to_time(value) + + @property + def recipients(self): + return self._recipients + + @recipients.setter + def recipients(self, value): + value['items'] = [Recipient().load(r) for r in value['items']] + self._recipients = value + + def __str__(self): + return "\n".join([ + "id : %s" % self.id , + "href : %s" % self.href , + "direction : %s" % self.direction , + "originator : %s" % self.originator , + "subject : %s" % self.subject , + "body : %s" % self.body , + "mediaUrls : %s" % ",".join(self.mediaUrls), + "reference : %s" % self.reference , + "scheduledDatetime : %s" % self.scheduledDatetime , + "createdDatetime : %s" % self.createdDatetime , + "recipients : %s" % self.recipients, + ]) \ No newline at end of file diff --git a/setup.py b/setup.py index e21ddbb..4edbdbb 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ from os import path from setuptools import setup +from io import open def get_description(): working_directory = path.abspath(path.dirname(__file__)) diff --git a/tests/test_mms.py b/tests/test_mms.py new file mode 100644 index 0000000..61ba3b0 --- /dev/null +++ b/tests/test_mms.py @@ -0,0 +1,27 @@ +import unittest +from messagebird import Client + +try: + from unittest.mock import Mock +except ImportError: + # mock was added to unittest in Python 3.3, but was an external library + # before. + from mock import Mock + + +class TestMMS(unittest.TestCase): + + def test_create_mms(self): + http_client = Mock() + http_client.request.return_value = '{"originator": "test-org", "body": "Rich test message", "direction": "mt", "recipients": {"totalCount": 1, "totalSentCount": 1, "totalDeliveredCount": 0, "totalDeliveryFailedCount": 0, "items": [{"status": "sent", "statusDatetime": "2019-06-04T13:54:48+00:00", "recipient": 4915238456487}]}, "reference": null, "createdDatetime": "2019-06-04T13:54:48+00:00", "href": "https://rest.messagebird.com/mms/0a75f8f82b5d4377bd8fb5b22ac1e8ac", "mediaUrls": ["https://www.messagebird.com/assets/images/og/messagebird.gif"], "scheduledDatetime": null, "id": "0a75f8f82b5d4377bd8fb5b22ac1e8ac", "subject": null}' + + params = {"originator": "test-org", "body": "Rich test message","recipients":"+4915238456487","mediaUrls":"https://www.messagebird.com/assets/images/og/messagebird.gif"} + mms = Client('', http_client).mms_create(**params) + + params["mediaUrls"] = [params["mediaUrls"]] + params.update({'subject': None, 'reference': None, 'scheduledDatetime': None}) + http_client.request.assert_called_once_with('mms', 'POST', params) + + self.assertEqual(params["originator"], mms.originator) + self.assertEqual(params["recipients"].strip("+"), str(mms.recipients["items"][0].recipient)) + self.assertEqual(1,len(mms.recipients["items"]))