Skip to content

Commit 1f8bbb2

Browse files
authored
[TOOLSLIBS-408] sms & mms updates (#175)
* rm isort for real * adds mms override and test * deurban * adds sms keyword interaction * rm unneeded var * adds shorten_links to sms override
1 parent 06eb406 commit 1f8bbb2

File tree

8 files changed

+284
-51
lines changed

8 files changed

+284
-51
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ repos:
1111
rev: 19.3b0
1212
hooks:
1313
- id: black
14-
- repo: https://github.com/timothycrosley/isort
15-
rev: 4.3.21
16-
hooks:
17-
- id: isort
1814
- repo: https://github.com/codespell-project/codespell
1915
rev: v1.16.0
2016
hooks:

tests/devices/test_sms.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
import json
23
import mock
34
import unittest
@@ -56,11 +57,7 @@ def test_sms_opt_out(self):
5657

5758
with mock.patch.object(ua.Airship, "_request") as mock_request:
5859
response = requests.Response()
59-
response._content = json.dumps(
60-
{
61-
"ok": True,
62-
}
63-
).encode("utf-8")
60+
response._content = json.dumps({"ok": True}).encode("utf-8")
6461
response.status_code = 202
6562
mock_request.return_value = response
6663

@@ -77,11 +74,7 @@ def test_sms_uninstall(self):
7774

7875
with mock.patch.object(ua.Airship, "_request") as mock_request:
7976
response = requests.Response()
80-
response._content = json.dumps(
81-
{
82-
"ok": True,
83-
}
84-
).encode("utf-8")
77+
response._content = json.dumps({"ok": True}).encode("utf-8")
8578
response.status_code = 202
8679
mock_request.return_value = response
8780

@@ -129,3 +122,31 @@ def test_sms_lookup(self):
129122
r = sms_obj.lookup()
130123

131124
self.assertTrue(r.ok)
125+
126+
127+
class TestSmsKeywordInteraction(unittest.TestCase):
128+
def setUp(self):
129+
self.airship = ua.Airship(TEST_KEY, TEST_SECRET)
130+
self.sender_ids = ["12345", "09876"]
131+
self.msisdn = "15035556789"
132+
self.keyword = "from_a_motel_six"
133+
self.timestamp = datetime(2014, 10, 8, 12, 0, 0)
134+
self.interaction = ua.KeywordInteraction(
135+
airship=self.airship,
136+
keyword=self.keyword,
137+
msisdn=self.msisdn,
138+
sender_ids=self.sender_ids,
139+
timestamp=self.timestamp,
140+
)
141+
142+
def test_payload(self):
143+
self.assertEqual(
144+
self.interaction.payload,
145+
{"keyword": self.keyword, "sender_ids": self.sender_ids},
146+
)
147+
148+
def test_url(self):
149+
self.assertEqual(
150+
self.interaction.url,
151+
"https://go.urbanairship.com/api/sms/15035556789/keywords",
152+
)

tests/push/test_push.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,11 @@ def test_sms_overrides(self):
349349
p.audience = ua.all_
350350
p.notification = ua.notification(
351351
alert="top level alert",
352-
sms=ua.sms(alert="sms override alert", expiry="2018-04-01T12:00:00"),
352+
sms=ua.sms(
353+
alert="sms override alert",
354+
expiry="2018-04-01T12:00:00",
355+
shorten_links=True,
356+
),
353357
)
354358
p.device_types = ua.device_types("sms")
355359

@@ -363,11 +367,44 @@ def test_sms_overrides(self):
363367
"sms": {
364368
"alert": "sms override alert",
365369
"expiry": "2018-04-01T12:00:00",
370+
"shorten_links": True,
366371
},
367372
},
368373
},
369374
)
370375

376+
def test_mms_overrides(self):
377+
mms_payload = ua.mms(
378+
fallback_text="an airbag saved my life",
379+
content_type="image/gif",
380+
url="https://c.tenor.com/ZhKMg4_yCTgAAAAC/surprised-pikachu.gif",
381+
shorten_links=True,
382+
content_length=1000,
383+
text="hey man slow down",
384+
subject="this is what you get",
385+
)
386+
387+
self.assertEqual(
388+
mms_payload,
389+
{
390+
"mms": {
391+
"subject": "this is what you get",
392+
"fallback_text": "an airbag saved my life",
393+
"shorten_links": True,
394+
"slides": [
395+
{
396+
"text": "hey man slow down",
397+
"media": {
398+
"url": "https://c.tenor.com/ZhKMg4_yCTgAAAAC/surprised-pikachu.gif",
399+
"content_type": "image/gif",
400+
"content_length": 1000,
401+
},
402+
}
403+
],
404+
}
405+
},
406+
)
407+
371408
def test_email_overrides(self):
372409
p = ua.Push(None)
373410
p.audience = ua.all_

urbanairship/__init__.py

Lines changed: 102 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,109 @@
1-
"""Python package for using the Urban Airship API"""
1+
"""Python package for using the Airship API"""
22
import logging
33

44
from .automation import Automation, Pipeline
55
from .common import AirshipFailure, Unauthorized
66
from .core import Airship
7-
from .devices import (APIDList, Attribute, AttributeResponse, ChannelInfo,
8-
ChannelList, ChannelTags, ChannelUninstall, DeviceInfo,
9-
DeviceTokenList, Email, EmailAttachment, EmailTags,
10-
LocationFinder, ModifyAttributes, NamedUser,
11-
NamedUserList, NamedUserTags, OpenChannel,
12-
OpenChannelTags, Segment, SegmentList, Sms, StaticList,
13-
StaticLists)
7+
from .devices import (
8+
APIDList,
9+
Attribute,
10+
AttributeResponse,
11+
ChannelInfo,
12+
ChannelList,
13+
ChannelTags,
14+
ChannelUninstall,
15+
DeviceInfo,
16+
DeviceTokenList,
17+
Email,
18+
EmailAttachment,
19+
EmailTags,
20+
KeywordInteraction,
21+
LocationFinder,
22+
ModifyAttributes,
23+
NamedUser,
24+
NamedUserList,
25+
NamedUserTags,
26+
OpenChannel,
27+
OpenChannelTags,
28+
Segment,
29+
SegmentList,
30+
Sms,
31+
StaticList,
32+
StaticLists,
33+
)
1434
from .experiments import ABTest, Experiment, Variant
15-
from .push import (CreateAndSendPush, Push, ScheduledList, ScheduledPush,
16-
Template, TemplateList, TemplatePush, absolute_date,
17-
actions, alias, all_, amazon, amazon_channel, and_, android,
18-
android_channel, apid, best_time, campaigns, channel,
19-
date_attribute, device_token, device_types, email, in_app,
20-
interactive, ios, ios_channel, local_scheduled_time,
21-
location, merge_data, message, named_user, not_,
22-
notification, number_attribute, open_channel, open_platform,
23-
options, or_, public_notification, recent_date,
24-
scheduled_time, segment, sms, sms_id, sms_sender, style,
25-
tag, tag_group, text_attribute, wearable, web, wns,
26-
wns_payload)
27-
from .reports import (AppOpensList, CustomEventsList, DevicesReport,
28-
ExperimentReport, IndividualResponseStats, OptInList,
29-
OptOutList, PushList, ResponseList, ResponseReportList,
30-
TimeInAppList, WebResponseReport)
35+
from .push import (
36+
CreateAndSendPush,
37+
Push,
38+
ScheduledList,
39+
ScheduledPush,
40+
Template,
41+
TemplateList,
42+
TemplatePush,
43+
absolute_date,
44+
actions,
45+
alias,
46+
all_,
47+
amazon,
48+
amazon_channel,
49+
and_,
50+
android,
51+
android_channel,
52+
apid,
53+
best_time,
54+
campaigns,
55+
channel,
56+
date_attribute,
57+
device_token,
58+
device_types,
59+
email,
60+
in_app,
61+
interactive,
62+
ios,
63+
ios_channel,
64+
local_scheduled_time,
65+
location,
66+
merge_data,
67+
message,
68+
mms,
69+
named_user,
70+
not_,
71+
notification,
72+
number_attribute,
73+
open_channel,
74+
open_platform,
75+
options,
76+
or_,
77+
public_notification,
78+
recent_date,
79+
scheduled_time,
80+
segment,
81+
sms,
82+
sms_id,
83+
sms_sender,
84+
style,
85+
tag,
86+
tag_group,
87+
text_attribute,
88+
wearable,
89+
web,
90+
wns,
91+
wns_payload,
92+
)
93+
from .reports import (
94+
AppOpensList,
95+
CustomEventsList,
96+
DevicesReport,
97+
ExperimentReport,
98+
IndividualResponseStats,
99+
OptInList,
100+
OptOutList,
101+
PushList,
102+
ResponseList,
103+
ResponseReportList,
104+
TimeInAppList,
105+
WebResponseReport,
106+
)
31107

32108
__all__ = [
33109
Airship,
@@ -51,6 +127,7 @@
51127
segment,
52128
sms_id,
53129
sms_sender,
130+
mms,
54131
and_,
55132
or_,
56133
not_,
@@ -126,6 +203,7 @@
126203
ModifyAttributes,
127204
WebResponseReport,
128205
ExperimentReport,
206+
KeywordInteraction,
129207
]
130208

131209

urbanairship/devices/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
from .named_users import NamedUser, NamedUserList, NamedUserTags
88
from .open_channel import OpenChannel
99
from .segment import Segment, SegmentList
10-
from .sms import Sms
10+
from .sms import Sms, KeywordInteraction
1111
from .static_lists import StaticList, StaticLists

urbanairship/devices/sms.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
import json
23
import logging
34
import re
@@ -14,7 +15,7 @@ class Sms(object):
1415
1516
:param airship: Required. An urbanairship.Airship object instantiated with
1617
master authentication.
17-
:param sender: Required. The a number that recipients will recieve SMS
18+
:param sender: Required. The a number that recipients will receive SMS
1819
notifications from. This must match your Urban Airship configuration.
1920
:param msisdn: Required. The mobile phone number you want to register as
2021
an SMS channel (or send a request to opt-in).
@@ -66,17 +67,11 @@ def msisdn(self, value):
6667

6768
@property
6869
def common_payload(self):
69-
return {
70-
"sender": self.sender,
71-
"msisdn": self.msisdn,
72-
}
70+
return {"sender": self.sender, "msisdn": self.msisdn}
7371

7472
@property
7573
def create_and_send_audience(self):
76-
audience = {
77-
"ua_sender": self.sender,
78-
"ua_msisdn": self.msisdn,
79-
}
74+
audience = {"ua_sender": self.sender, "ua_msisdn": self.msisdn}
8075

8176
if self.template_fields:
8277
audience.update(self.template_fields)
@@ -181,3 +176,43 @@ def lookup(self):
181176
response = self.airship.request(method="GET", body=None, url=url, version=3)
182177

183178
return response
179+
180+
181+
class KeywordInteraction(object):
182+
def __init__(self, airship, keyword, msisdn, sender_ids, timestamp=None):
183+
self.airship = airship
184+
self.keyword = keyword
185+
self.msisdn = msisdn
186+
self.sender_ids = sender_ids
187+
self.timestamp = timestamp
188+
189+
if type(sender_ids) is not list:
190+
raise ValueError("sender_ids must be a list")
191+
192+
@property
193+
def timestamp(self):
194+
return self._timestamp.replace(microsecond=0).isoformat()
195+
196+
@timestamp.setter
197+
def timestamp(self, value):
198+
if type(value) is not datetime and value is not None:
199+
raise ValueError("timestamp must be a datetime object")
200+
201+
self._timestamp = value
202+
203+
@property
204+
def payload(self):
205+
return {"keyword": self.keyword, "sender_ids": self.sender_ids}
206+
207+
@property
208+
def url(self):
209+
return "{base_url}sms/{msisdn}/keywords".format(
210+
base_url=self.airship.urls.get("base_url"), msisdn=self.msisdn
211+
)
212+
213+
def post(self):
214+
response = self.airship.request(
215+
method="POST", url=self.url, body=self.payload, version=3
216+
)
217+
218+
return response

urbanairship/push/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
interactive,
3737
ios,
3838
message,
39+
mms,
3940
notification,
4041
open_platform,
4142
options,
@@ -92,6 +93,7 @@
9293
amazon,
9394
web,
9495
sms,
96+
mms,
9597
wns_payload,
9698
open_platform,
9799
message,

0 commit comments

Comments
 (0)