Parse.com supports Push Notification. I can send a push notification from the dashboard with a UI that is easy to understand, Alternatively, you can use the REST API to send push notifications from the app side. It was a little difficult to understand how to finely control using DeviceToken, so I will write about it.
Push notification requires at least ʻalert, so if you use
curl, specify as follows and send. The
X-Parse-Application-Id (Application ID) and
X-Parse-REST-API-Key` (REST API Key) can be obtained from the Dashboard Overview.
After that, if you are logged in and looking at the Document, you can execute it as it is because the Key is directly embedded in the code example !!
curl -X POST \
-H "X-Parse-Application-Id: <Application ID>" \
-H "X-Parse-REST-API-Key: <REST API Key>" \
-H "Content-Type: application/json" \
-d '{
"data": {
"alert": "The Giants won against the Mets 2-3."
}
}' \
https://api.parse.com/1/push
In simple terms, it will be in the JSON format below.
Since the condition is specified in where
, you can send Push Notificaiton to a specific terminal by specifying deviceToken
here.
--In place of data
, put the notification data of iOS or Android
--Easy to specify the date and time of transmission and expiration date
--Condition Query can be specified in place of where
--Since general conditional operators such as $ lt
(less then) and $ in
(contained in) are available, flexible requests are possible.
parse_push.py
{'where': {'deviceToken': [], #Condition specification using Query API
},
'push_time': '2013-01-23T12:00:00Z', #Notification start date and time(iso)
'expiration_interval': '518400', #expiration date
'expiration_time': '2013-01-23T21:08:39Z', #Expiration date and time specified(iso)
'data': {
'alert': 'message',
'badge': 'Increment', # Number or 'Increment'(iOS only).
'sound': 'sound bundle', # iOS only.
'content-available': '1', # Newsstand content count(iOS only).
'action': 'Intent', # Android only.
'title': 'Notification!!', # Android only.
}
}
If you specify the conditional operator, it looks like this.
parse_push2.py
{'data': {'alert': 'push notification message!',
'badge': 'Increment',
'sound': 'default'},
'where': {'deviceToken': {'$in': [u'<deviceToken1>', u'<deviceToken2>']}}}
Written in Python, it looks like this.
apn.py
# coding: utf-8
PARSE_API_BASE = 'https://api.parse.com'
PARSE_PUSH_API = '/1/push'
PARSE_PUSH_URL = PARSE_API_BASE + PARSE_PUSH_API
#Specify the Key required for Push Notification with HTTP Header
HEADERS = {
"X-Parse-Application-Id": "<Application ID>",
"X-Parse-REST-API-Key": "<REST API Key>",
"X-Parse-Master-Key": "<Master Key>",
"Content-Type": "application/json"
}
class APNMessageQueue(object):
""" APN(Apple Push notification)Save messages for
"""
structure = {
'user_id': lambda x: (x is not None and len(x) > 0),
'notify_token': lambda x: (x is not None and len(x) > 0),
'message': lambda x: (x is not None and len(x) > 0),
}
def __init__(self, *args, **kwargs):
for k in self.structure.keys():
self.__setattr__(k, kwargs.get(k, None))
@classmethod
def create(cls, user_id, notify_token, message):
src_props = dict(
user_id=user_id,
notify_token=notify_token,
message=message,
)
props = {}
for k, func in cls.structure.iteritems():
value = src_props.get(k)
if func(value):
props[k] = value
if props:
return APNMessageQueue(**props)
return None
def create_notify_message(message, badge='Increment', sound='default'):
"""Create Push Notification format from Notification message
Args:
message:Alert message.
badge:Batch count('Increment'Is Parse.com original).
sound:Notification sound effect.
Return:
PushNotification format string.
"""
return {'alert': message, 'badge': badge, 'sound': sound}
def create_request_data(notify_token, apn_data):
"""Parse Notification format Template format data creation
Args:
notify_token:Device token or list of it.
apn_data:Apple Push Notification data.
Returns:
ParseNotification format Template format data.
"""
request_data = {'data': apn_data}
if isinstance(notify_token, list):
request_data['where'] = {'deviceToken': {'$in': notify_token}}
else:
request_data['where'] = {'deviceToken': notify_token}
return request_data
def process_do_send(request_data):
"""ParseNotification format Send PushNotification by passing template format data
Args:
request_data:ParseNotification format Template format data
Returns:
Returns normal termination or error
"""
import json
from urllib2 import Request, urlopen, URLError
payload = json.dumps(request_data)
request = Request(PARSE_PUSH_URL, payload, HEADERS)
try:
response = urlopen(request)
data = json.loads(response.read())
if isinstance(data, dict):
return data.get('result', False)
except URLError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: %s' % e.reason
elif hasattr(e, 'code'):
print 'The server couldn\'t fulfill the request.'
print 'Error code: %d' % e.code
return False
def send_notification(notify_queue_list):
"""Send Push Notification to APNs
Broadcast Push Notification message to APNs server
Args:
notify_queue_list:APNMessageQueue list
"""
from itertools import groupby
notify_sorted_queue_list = sorted(notify_queue_list, key=lambda x: x.message)
#Send the same message together
for message, group in groupby(notify_sorted_queue_list, key=lambda x: x.message):
distict_tokens = list(set([user.notify_token for user in group]))
aps_data = create_notify_message(message)
request_data = create_request_data(distict_tokens, aps_data)
print request_data
process_do_send(request_data)
The user side is like this
main.py
# coding: utf-8
def send_push_parse_for_apn(message):
import models
import apn
#Get a list of deviceTokens for Notification from user data
targets = [x for x in models.User.find_by_existing_notify_token() if x is not None]
notify_token_list = [apn.APNMessageQueue(x.user_id, x.notify_token, message) for x in targets]
if len(notify_token_list) > 0:
#Launch
apn.send_notification(notify_token_list)
if __name__ == '__main__':
send_push_parse_for_apn('Abo!!')
Recommended Posts