1+ import base64
12import json
23import logging
34import re
@@ -16,7 +17,7 @@ class Email(object):
1617
1718 Please see the email documentation for important information about
1819 opt-in times and email types.
19- https ://docs.urbanairship .com/api/ua/#operation/api/channels/ email
20+ hhttps ://docs.airship .com/api/ua/#tag- email
2021
2122 :param address: Required. The email address the object represents.
2223 :param commercial_opted_in: Optional. A string in ISO 8601 format that
@@ -34,6 +35,12 @@ class Email(object):
3435 to locale country setting.
3536 :param locale_language: Optional. The device property tag related
3637 to locale language setting.
38+ :param opt_in_mode: Optional. The opt-in mode for registering the channel. `classic`
39+ is the default when unspecified, `double` creates a `double_opt_in` event.
40+ :param properties: Optional. An object containing event properties. You can use
41+ these properties to filter the double opt-in event and reference them in your
42+ message content by using handlebars. Items in the `properties` object are
43+ limited to a 255-character maximum string length.
3744 :param timezone: Optional. The deice property tag related to
3845 timezone setting.
3946 :param template_fields: For use with CreateAndSend with inline templates.
@@ -50,6 +57,8 @@ def __init__(
5057 transactional_opted_out = None ,
5158 locale_country = None ,
5259 locale_language = None ,
60+ opt_in_mode = None ,
61+ properties = None ,
5362 timezone = None ,
5463 template_fields = None ,
5564 ):
@@ -61,6 +70,8 @@ def __init__(
6170 self .transactional_opted_out = transactional_opted_out
6271 self .locale_country = locale_country
6372 self .locale_language = locale_language
73+ self .opt_in_mode = opt_in_mode
74+ self .properties = properties
6475 self .timezone = timezone
6576 self .template_fields = template_fields
6677 self ._email_type = "email" # only acceptable value at this time
@@ -77,6 +88,17 @@ def template_fields(self, value):
7788
7889 self ._template_fields = value
7990
91+ @property
92+ def opt_in_mode (self ):
93+ return self ._opt_in_mode
94+
95+ @opt_in_mode .setter
96+ def opt_in_mode (self , value ):
97+ if value not in ["classic" , "double" ] and value is not None :
98+ raise ValueError ("opt_in_mode must be one of: 'classic' or 'double'" )
99+
100+ self ._opt_in_mode = value
101+
80102 @property
81103 def address (self ):
82104 return self ._address
@@ -129,9 +151,7 @@ def transactional_opted_out(self, value):
129151
130152 @property
131153 def create_and_send_audience (self ):
132- audience = {
133- "ua_address" : self .address ,
134- }
154+ audience = {"ua_address" : self .address }
135155 if self .commercial_opted_in :
136156 audience ["ua_commercial_opted_in" ] = self .commercial_opted_in
137157 if self .transactional_opted_in :
@@ -150,12 +170,7 @@ def register(self):
150170 :return: The response object from the API.
151171 """
152172 url = self .airship .urls .get ("email_url" )
153- reg_payload = {
154- "channel" : {
155- "type" : self ._email_type ,
156- "address" : self .address ,
157- }
158- }
173+ reg_payload = {"channel" : {"type" : self ._email_type , "address" : self .address }}
159174
160175 if self .commercial_opted_in :
161176 reg_payload ["channel" ]["commercial_opted_in" ] = self .commercial_opted_in
@@ -176,6 +191,10 @@ def register(self):
176191 reg_payload ["channel" ]["locale_country" ] = self .locale_country
177192 if self .timezone is not None :
178193 reg_payload ["channel" ]["timezone" ] = self .timezone
194+ if self .opt_in_mode is not None :
195+ reg_payload ["channel" ]["opt_in_mode" ] = self .opt_in_mode
196+ if self .properties is not None :
197+ reg_payload ["channel" ]["properties" ] = self .properties
179198
180199 body = json .dumps (reg_payload ).encode ("utf-8" )
181200
@@ -215,6 +234,17 @@ def uninstall(self):
215234
216235 return response
217236
237+ @classmethod
238+ def lookup (cls , airship , address ):
239+ if not VALID_EMAIL .match (address ) and address is not None :
240+ raise ValueError ("Invalid email address format" )
241+
242+ url = airship .urls .get ("email_url" ) + address
243+
244+ response = airship .request (method = "GET" , url = url , version = 3 , body = None )
245+
246+ return response
247+
218248
219249class EmailTags (object ):
220250 """Add, remove or set tags for a list of email addresses
@@ -303,3 +333,54 @@ def send(self):
303333 )
304334
305335 return response
336+
337+
338+ class EmailAttachment (object ):
339+ """
340+ Create an email attachment from a file.
341+ Please see https://docs.airship.com/api/ua/#operation/api/attachments/post
342+ for important information about file size, content type, and send type limitations.
343+
344+ :param filename: Required. The name of the uploaded file (max 255 UTF-8 bytes).
345+ Multiple files with the same name are allowed in separate requests.
346+ :param content_type: Required: The mimetype of the uploaded file including the
347+ charset parameter, if needed.
348+ :param filepath: Required. A path to the file to be uploaded and attached. File must
349+ have permissions set to be opened in 'rb' (binary) mode.
350+
351+ :return: the response object from the API including the 'attachment_ids' uuid to
352+ be used in the email override object.
353+ """
354+
355+ def __init__ (self , airship , filename , content_type , filepath ):
356+ self .airship = airship
357+ self .filename = filename
358+ self .content_type = content_type
359+ self .filepath = filepath
360+
361+ def _encode_attachment (self , filepath ):
362+ file = open (filepath , "rb" ).read ()
363+ enc = base64 .urlsafe_b64encode (file )
364+
365+ return str (enc )
366+
367+ @property
368+ def req_payload (self ):
369+ attachment_payload = {
370+ "filename" : self .filename ,
371+ "content_type" : self .content_type ,
372+ "data" : self ._encode_attachment (self .filepath ),
373+ }
374+
375+ return attachment_payload
376+
377+ def post (self ):
378+ response = self .airship .request (
379+ method = "POST" ,
380+ body = json .dumps (self .req_payload ),
381+ url = self .airship .urls .get ("attachment_url" ),
382+ content_type = "application/json" ,
383+ version = 3 ,
384+ )
385+
386+ return response .json ()
0 commit comments