forked from geeknam/python-gcm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmulticast_client_sample.py
More file actions
80 lines (67 loc) · 3.23 KB
/
Copy pathmulticast_client_sample.py
File metadata and controls
80 lines (67 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from datetime import datetime
import time
from django.utils.encoding import smart_str
from gcm import GCM
from gcm.gcm import GCMRetriableException
MY_EXCELLENT_GCM_KEY = 'my excellent gcm key' # replace with your key, or supply it via another means
def send_notification(ids, devices_by_reg_id, payload, max_attempts=3):
"""
Send a message to multiple devices via Google GCM system's multicast feature.
Since the gcm system provides feedback as a summary after attempting all messages,
we record success/failure of a given device
within this routine.
@param ids: list of keys within devices_by_reg_id
@param devices_by_reg_id: dictionary of device (mobile/tablet etc.) that will receive notification
@param payload: message to send
@return True if ALL ids were handled by GCM (success or failure, but handled), False otherwise (such as a network failure)
"""
if not ids or not payload or not devices_by_reg_id:
return False
# assume NO collapsing of messages together--try to send all to device when device comes back online.
# note that collapse_key cannot be None if time_to_live is not None
collapse_key = str(datetime.now())
delay_while_idle = False
time_to_live = 3600
for i in xrange(max_attempts):
try:
gcm_response = GCM(MY_EXCELLENT_GCM_KEY).request_json(
ids, payload, collapse_key, delay_while_idle, time_to_live)
parse_response(devices_by_reg_id, gcm_response, ids)
should_retry = gcm_response.has_resends()
if should_retry:
ids = gcm_response.get_resend_ids(ids) # reset ids for next try
if i < max_attempts - 1:
time.sleep(0.20) # TODO back off exponentially
else:
break # record failures below
else:
return True # FINISHED! successes already recorded
except GCMRetriableException:
if i < max_attempts - 1:
time.sleep(0.20) # TODO back off exponentially
else:
break
except Exception as e:
print('problem with gcm: %s' % smart_str(e))
break
# the attempt failed if we got here.
for fail_id in ids:
if devices_by_reg_id.has_key(fail_id):
d = devices_by_reg_id[fail_id]
# record_fail(d.user_id, d.id)
return False
def parse_response(devices_by_reg_id, gcm_response, ids):
for (old_reg_id, canonical_id) in gcm_response.get_canonical_ids(ids):
if devices_by_reg_id.has_key(old_reg_id):
d = devices_by_reg_id[old_reg_id]
d.registration_id = canonical_id # Replace reg_id with canonical_id in your database
d.save()
for old_invalid_id in gcm_response.get_unregister_errors(ids):
if devices_by_reg_id.has_key(old_invalid_id):
d = devices_by_reg_id[old_invalid_id]
d.registration_id = ''
d.save() # this should happen right away, since all future notifications should be skipped
for success_id in gcm_response.get_successes(ids):
if devices_by_reg_id.has_key(success_id):
d = devices_by_reg_id[success_id]
# record_success(d.user_id, d.id)