Commits

Matt Good  committed f9dc74b

Batch push API

  • Participants
  • Parent commits 3da25ba

Comments (0)

Files changed (1)

File urbanairship.py

 BASE_URL = "https://go.urbanairship.com/api"
 DEVICE_TOKEN_URL = BASE_URL + '/device_tokens/'
 PUSH_URL = BASE_URL + '/push/'
+BATCH_PUSH_URL = BASE_URL + '/push/batch/'
 BROADCAST_URL = BASE_URL + '/push/broadcast/'
 FEEDBACK_URL = BASE_URL + '/device_tokens/feedback/'
 
     """
 
 
+def _payload(payload, device_tokens=None, aliases=None, tags=None):
+    """Helper function to generate APNS payload dict"""
+    payload = dict(payload) # make a copy to modify
+    if device_tokens:
+        payload['device_tokens'] = device_tokens
+    if aliases:
+        payload['aliases'] = aliases
+    if tags:
+        payload['tags'] = tags
+    return payload
+
+
+class AirshipBatch(object):
+    """Helper class to build batch pushes.
+
+    batch = airship.batch()
+    batch.push({'aps': {'alert': 'Hello'}}, device_tokens=['1234'])
+    batch.push({'aps': {'alert': 'Goodbye'}}, aliases=['some_alias'])
+    batch.send()
+
+    Also supports chaining calls to .push():
+
+    (airship.batch()
+            .push({'aps': {'alert': 'Hello'}}, device_tokens=['1234'])
+            .push({'aps': {'alert': 'Goodbye'}}, aliases=['some_alias'])
+            .send())
+
+    The batch is cleared after a .send() and can be re-used to send other
+    batches:
+
+    batch = airship.batch()
+    batch.push({'aps': {'alert': 'Hello'}}, device_tokens=['1234'])
+    batch.send()
+
+    batch.push({'aps': {'alert': 'Goodbye'}}, aliases=['some_alias'])
+    batch.send()
+    """
+
+    def __init__(self, airship):
+        self._airship = airship
+        self._payloads = []
+
+    def push(self, payload, device_tokens=None, aliases=None, tags=None):
+        payload = _payload(payload, device_tokens=device_tokens,
+                           aliases=aliases, tags=tags)
+        self._payloads.append(payload)
+        return self # allow chaining
+
+    def send(self):
+        if not self._payloads:
+          return
+        self._airship._send_batch(self._payloads)
+        self._payloads = []
+
+
 class AirshipDeviceList(object):
     """Iterator that fetches and returns a list of device tokens
 
 
     def push(self, payload, device_tokens=None, aliases=None, tags=None):
         """Push this payload to the specified device tokens and tags."""
-        if device_tokens:
-            payload['device_tokens'] = device_tokens
-        if aliases:
-            payload['aliases'] = aliases
-        if tags:
-            payload['tags'] = tags
+        payload = _payload(payload, device_tokens=device_tokens,
+                           aliases=aliases, tags=tags)
         body = json.dumps(payload)
         status, response = self._request('POST', body, PUSH_URL,
             'application/json')
         if not status == 200:
             raise AirshipFailure(status, response)
 
+    def batch(self):
+        return AirshipBatch(self)
+
+    def _send_batch(self, payloads):
+        body = json.dumps(payloads)
+        status, response = self._request('POST', body, BATCH_PUSH_URL,
+                                         'application/json')
+        if status != 200:
+            raise AirshipFailure(status, response)
+
     def broadcast(self, payload, exclude_tokens=None):
         """Broadcast this payload to all users."""
         if exclude_tokens: