def post(self): """Create a new token """ if not self.can("create_token"): self.send_response(FORBIDDEN, dict(error="No permission to create token")) return data = self.json_decode(self.request.body) device = data.get('device', DEVICE_TYPE_IOS).lower() channel = data.get('channel', 'default') devicetoken = data.get('token', '') if device == DEVICE_TYPE_IOS: if len(devicetoken) != 64: self.send_response(BAD_REQUEST, dict(error='Invalid token')) return try: binascii.unhexlify(devicetoken) except Exception as ex: self.send_response(BAD_REQUEST, dict(error='Invalid token')) token = EntityBuilder.build_token(devicetoken, device, self.appname, channel) try: result = self.db.tokens.update({'device': device, 'token': devicetoken, 'appname': self.appname}, token, safe=True, upsert=True) # result # {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1} if result['updatedExisting']: self.add_to_log('Token exists', devicetoken) self.send_response(OK) else: self.send_response(OK) self.add_to_log('Add token', devicetoken) except Exception as ex: self.add_to_log('Cannot add token', devicetoken, "warning") self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
def post(self): """Create a new token """ if not self.can("create_token"): self.send_response(FORBIDDEN, dict(error="No permission to create token")) return logging.info(self.request.body) data = json_decode(self.request.body) device = data.get("device", DEVICE_TYPE_IOS).lower() channel = data.get("channel", "default") devicetoken = data.get("token", "") if device == DEVICE_TYPE_IOS: if len(devicetoken) != 64: self.send_response(BAD_REQUEST, dict(error="Invalid token")) return try: binascii.unhexlify(devicetoken) except Exception as ex: self.send_response(BAD_REQUEST, dict(error="Invalid token")) token = EntityBuilder.build_token(devicetoken, device, self.appname, channel) try: result = self.db.tokens.update( { "device": device, "token": devicetoken, "appname": self.appname }, token, upsert=True, ) # result # {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1} if result["updatedExisting"]: self.add_to_log("Token exists", devicetoken) self.send_response(OK) else: self.send_response(OK) self.add_to_log("Add token", devicetoken) except Exception as ex: self.add_to_log("Cannot add token", devicetoken, "warning") self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
async def post(self): try: """ Send notifications """ if not self.can("send_notification"): self.send_response( FORBIDDEN, dict(error="No permission to send notification")) return # if request body is json entity request_dict = json_decode(self.request.body) # application specific request_dict extra = request_dict.get("extra", {}) # Hook if "processor" in extra: try: proc = import_module("hooks." + extra["processor"]) request_dict = proc.process_pushnotification_payload( request_dict) except Exception as ex: logging.error(str(ex)) self.send_response(BAD_REQUEST, dict(error=str(ex))) return if not self.token: self.token = request_dict.get("token", None) device = request_dict.get("device", DEVICE_TYPE_FCM).lower() channel = request_dict.get("channel", "default") alert = request_dict.get("alert", "") token = self.dao.find_token(self.token) if not token: token = EntityBuilder.build_token(self.token, device, self.appname, channel) if not self.can("create_token"): self.send_response( BAD_REQUEST, dict( error= "Unknow token and you have no permission to create" ), ) return try: # TODO check permission to insert self.dao.add_token(token) except Exception as ex: logging.error(str(ex)) self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) return logging.info("sending notification to %s: %s" % (device, self.token)) # if device in [DEVICE_TYPE_FCM, DEVICE_TYPE_ANDROID]: if device.endswith(DEVICE_TYPE_FCM): fcm = request_dict.get("fcm", {}) try: fcmconn = self.fcmconnections[self.app["shortname"]][0] await fcmconn.process(token=self.token, alert=alert, fcm=fcm) except Exception as ex: statuscode = ex.code # reference: # https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode response_json = json_decode(ex.response.body) logging.error(response_json) self.add_to_log( "error", tornado.escape.to_unicode(ex.response.body)) self.send_response(statuscode, dict(error="error response from fcm")) return elif device == DEVICE_TYPE_IOS: # Use splitlines trick to remove line ending (only for iOS). if type(alert) is not dict: alert = "".join(alert.splitlines()) # https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW1 apns_default = { "badge": None, "sound": "default", "push_type": "alert" } apnspayload = request_dict.get("apns", request_dict.get("fcm", {})) conn = self.get_apns_conn() if conn: try: conn.process( token=self.token, alert=alert, apns={ **apns_default, **apnspayload }, ) except Exception as ex: logging.error(ex) self.reattempt_push_apns(alert, apnspayload, self.token) return else: logging.error("no active apns connection") elif device == DEVICE_TYPE_WNS: request_dict.setdefault("wns", {}) wns = self.wnsconnections[self.app["shortname"]][0] wns.process( token=request_dict["token"], alert=alert, extra=extra, wns=request_dict["wns"], ) else: logging.error("invalid device type %s" % device) self.send_response(BAD_REQUEST, dict(error="Invalid device type")) return logmessage = "payload: %s, access key: %s" % ( tornado.escape.to_unicode(self.request.body), self.appkey, ) self.add_to_log("notification", logmessage) self.send_response(ACCEPTED) except Exception as ex: traceback_ex = traceback.format_exc() logging.error("%s %s" % (traceback_ex, str(ex))) self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
def post(self): try: logging.info("New Push request from IP:%s" % self.request.remote_ip) """ Send notifications """ if not self.can("send_notification"): self.send_response( FORBIDDEN, dict(error="No permission to send notification")) return # if request body is json entity data = self.json_decode(self.request.body) data = self.validate_data(data) # Hook #if 'extra' in data: # logging.info ("Extra data found") # if 'processor' in data['extra']: # try: # proc = import_module('hooks.' + data['extra']['processor']) # data = proc.process_pushnotification_payload(data) # except Exception, ex: # self.send_response(BAD_REQUEST, dict(error=str(ex))) if not self.token: self.token = data.get('token', None) # application specific data extra = data.get('extra', {}) device = data.get('device', DEVICE_TYPE_IOS).lower() channel = data.get('channel', 'default') token = self.db.tokens.find_one({'token': self.token}) if not token: token = EntityBuilder.build_token(self.token, device, self.appname, channel) if not self.can("create_token"): self.send_response( BAD_REQUEST, dict( error= "Unknow token and you have no permission to create" )) return try: # TODO check permission to insert self.db.tokens.insert(token, safe=True) except Exception as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) logmessage = 'requested by:%s, Message length: %s, Access key: %s, device token: %s' % ( self.request.remote_ip, len( data['alert']), self.appkey, self.token) self.add_to_log('%s notification' % self.appname, logmessage) if device == DEVICE_TYPE_SMS: data.setdefault('sms', {}) data['sms'].setdefault('to', data.get('token', '')) data['sms'].setdefault('message', data.get('message', '')) sms = self.smsconnections[self.app['shortname']][0] sms.process(token=data['token'], alert=data['alert'], extra=extra, sms=data['sms']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_IOS: # Use sliptlines trick to remove line ending (only for iOs). alert = ''.join(data['alert'].splitlines()) data.setdefault('apns', {}) data['apns'].setdefault('badge', data.get('badge', None)) data['apns'].setdefault('sound', data.get('sound', None)) data['apns'].setdefault('custom', data.get('custom', None)) self.get_apns_conn().process(token=self.token, alert=alert, extra=extra, apns=data['apns']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_ANDROID: data.setdefault('gcm', {}) try: gcm = self.gcmconnections[self.app['shortname']][0] data['gcm'].setdefault('soundname', data.get('sound', None)) logging.info('GCM API: Set soundname to %s' % data['sound']) response = gcm.process(token=[self.token], alert=data['alert'], extra=extra, gcm=data['gcm']) responsedata = response.json() if responsedata['failure'] == 0: self.send_response(ACCEPTED) except GCMUpdateRegIDsException as ex: self.send_response(ACCEPTED) except GCMInvalidRegistrationException as ex: self.send_response(BAD_REQUEST, dict(error=str(ex), regids=ex.regids)) except GCMNotRegisteredException as ex: self.send_response(BAD_REQUEST, dict(error=str(ex), regids=ex.regids)) except GCMException as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) elif device == DEVICE_TYPE_WNS: data.setdefault('wns', {}) wns = self.wnsconnections[self.app['shortname']][0] wns.process(token=data['token'], alert=data['alert'], extra=extra, wns=data['wns']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_MPNS: data.setdefault('mpns', {}) mpns = self.mpnsconnections[self.app['shortname']][0] mpns.process(token=data['token'], alert=data['alert'], extra=extra, mpns=data['mpns']) self.send_response(ACCEPTED) else: self.send_response(BAD_REQUEST, dict(error='Invalid device type')) except Exception, ex: import traceback traceback.print_exc() self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
def post(self): try: logging.info ("New Push request from IP:%s" % self.request.remote_ip) """ Send notifications """ if not self.can("send_notification"): self.send_response(FORBIDDEN, dict(error="No permission to send notification")) return # if request body is json entity data = self.json_decode(self.request.body) data = self.validate_data(data) # Hook #if 'extra' in data: # logging.info ("Extra data found") # if 'processor' in data['extra']: # try: # proc = import_module('hooks.' + data['extra']['processor']) # data = proc.process_pushnotification_payload(data) # except Exception, ex: # self.send_response(BAD_REQUEST, dict(error=str(ex))) if not self.token: self.token = data.get('token', None) # application specific data extra = data.get('extra', {}) device = data.get('device', DEVICE_TYPE_IOS).lower() channel = data.get('channel', 'default') token = self.db.tokens.find_one({'token': self.token}) if not token: token = EntityBuilder.build_token(self.token, device, self.appname, channel) if not self.can("create_token"): self.send_response(BAD_REQUEST, dict(error="Unknow token and you have no permission to create")) return try: # TODO check permission to insert self.db.tokens.insert(token, safe=True) except Exception as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) logmessage = 'requested by:%s, Message length: %s, Access key: %s, device token: %s' %( self.request.remote_ip, len(data['alert']), self.appkey, self.token) self.add_to_log('%s notification' % self.appname, logmessage) if device == DEVICE_TYPE_SMS: data.setdefault('sms', {}) data['sms'].setdefault('to', data.get('token', '')) data['sms'].setdefault('message', data.get('message', '')) sms = self.smsconnections[self.app['shortname']][0] sms.process(token=data['token'], alert=data['alert'], extra=extra, sms=data['sms']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_IOS: # Use sliptlines trick to remove line ending (only for iOs). alert = ''.join(data['alert'].splitlines()) data.setdefault('apns', {}) data['apns'].setdefault('badge', data.get('badge', None)) data['apns'].setdefault('sound', data.get('sound', None)) data['apns'].setdefault('custom', data.get('custom', None)) self.get_apns_conn().process(token=self.token, alert=alert, extra=extra, apns=data['apns']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_ANDROID: data.setdefault('gcm', {}) try: gcm = self.gcmconnections[self.app['shortname']][0] data['gcm'].setdefault('soundname', data.get('sound', None)) logging.info ('GCM API: Set soundname to %s' % data['sound']) response = gcm.process(token=[self.token], alert=data['alert'], extra=extra, gcm=data['gcm']) responsedata = response.json() if responsedata['failure'] == 0: self.send_response(ACCEPTED) except GCMUpdateRegIDsException as ex: self.send_response(ACCEPTED) except GCMInvalidRegistrationException as ex: self.send_response(BAD_REQUEST, dict(error=str(ex), regids=ex.regids)) except GCMNotRegisteredException as ex: self.send_response(BAD_REQUEST, dict(error=str(ex), regids=ex.regids)) except GCMException as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) elif device == DEVICE_TYPE_WNS: data.setdefault('wns', {}) wns = self.wnsconnections[self.app['shortname']][0] wns.process(token=data['token'], alert=data['alert'], extra=extra, wns=data['wns']) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_MPNS: data.setdefault('mpns', {}) mpns = self.mpnsconnections[self.app['shortname']][0] mpns.process(token=data['token'], alert=data['alert'], extra=extra, mpns=data['mpns']) self.send_response(ACCEPTED) else: self.send_response(BAD_REQUEST, dict(error='Invalid device type')) except Exception, ex: import traceback traceback.print_exc() self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))
def post(self): try: """ Send notifications """ if not self.can("send_notification"): self.send_response( FORBIDDEN, dict(error="No permission to send notification") ) return # if request body is json entity requestPayload = self.json_decode(self.request.body) requestPayload = self.validate_payload(requestPayload) # Hook if "extra" in requestPayload: if "processor" in requestPayload["extra"]: try: proc = import_module( "hooks." + requestPayload["extra"]["processor"] ) requestPayload = proc.process_pushnotification_payload( requestPayload ) except Exception as ex: self.send_response(BAD_REQUEST, dict(error=str(ex))) if not self.token: self.token = requestPayload.get("token", None) # application specific requestPayload extra = requestPayload.get("extra", {}) device = requestPayload.get("device", DEVICE_TYPE_IOS).lower() channel = requestPayload.get("channel", "default") token = self.db.tokens.find_one({"token": self.token}) if not token: token = EntityBuilder.build_token( self.token, device, self.appname, channel ) if not self.can("create_token"): self.send_response( BAD_REQUEST, dict(error="Unknow token and you have no permission to create"), ) return try: # TODO check permission to insert self.db.tokens.insert(token) except Exception as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) if device == DEVICE_TYPE_SMS: requestPayload.setdefault("sms", {}) requestPayload["sms"].setdefault("to", requestPayload.get("token", "")) requestPayload["sms"].setdefault( "message", requestPayload.get("message", "") ) sms = self.smsconnections[self.app["shortname"]][0] sms.process( token=requestPayload["token"], alert=requestPayload["alert"], extra=extra, sms=requestPayload["sms"], ) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_IOS: # Use splitlines trick to remove line ending (only for iOS). if type(requestPayload["alert"]) is not dict: alert = "".join(requestPayload["alert"].splitlines()) else: alert = requestPayload["alert"] requestPayload.setdefault("apns", {}) requestPayload["apns"].setdefault( "badge", requestPayload.get("badge", None) ) requestPayload["apns"].setdefault( "sound", requestPayload.get("sound", None) ) requestPayload["apns"].setdefault( "content", requestPayload.get("content", None) ) requestPayload["apns"].setdefault( "custom", requestPayload.get("custom", None) ) conn = self.get_apns_conn() if conn: conn.process( token=self.token, alert=alert, extra=extra, apns=requestPayload["apns"], ) else: _logger.error("no active apns connection") self.send_response(ACCEPTED) elif device == DEVICE_TYPE_FCM or device == DEVICE_TYPE_IOS_FCM or device == DEVICE_TYPE_ANDROID_FCM: requestPayload.setdefault("fcm", {}) try: fcm = self.fcmconnections[self.app["shortname"]][0] response = fcm.process( token=self.token, alert=requestPayload["alert"], extra=requestPayload["extra"], fcm=requestPayload["fcm"], ) self.send_response(ACCEPTED) except FCMException as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=ex.error)) elif device == DEVICE_TYPE_ANDROID: if "gcm" not in requestPayload: requestPayload.setdefault("gcm", {}) try: gcm = self.gcmconnections[self.app["shortname"]][0] response = gcm.process( token=[self.token], alert=requestPayload["alert"], extra=requestPayload["extra"], gcm=requestPayload["gcm"], ) responserequestPayload = response.json() if responserequestPayload["failure"] == 0: self.send_response(ACCEPTED) except GCMUpdateRegIDsException as ex: self.send_response(ACCEPTED) except GCMInvalidRegistrationException as ex: self.send_response( BAD_REQUEST, dict(error=str(ex), regids=ex.regids) ) except GCMNotRegisteredException as ex: self.send_response( BAD_REQUEST, dict(error=str(ex), regids=ex.regids) ) except GCMException as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) elif device == DEVICE_TYPE_WNS: requestPayload.setdefault("wns", {}) wns = self.wnsconnections[self.app["shortname"]][0] wns.process( token=requestPayload["token"], alert=requestPayload["alert"], extra=extra, wns=requestPayload["wns"], ) self.send_response(ACCEPTED) elif device == DEVICE_TYPE_MPNS: requestPayload.setdefault("mpns", {}) mpns = self.mpnsconnections[self.app["shortname"]][0] mpns.process( token=requestPayload["token"], alert=requestPayload["alert"], extra=extra, mpns=requestPayload["mpns"], ) self.send_response(ACCEPTED) else: self.send_response(BAD_REQUEST, dict(error="Invalid device type")) logmessage = "Message length: %s, Access key: %s" % ( len(requestPayload["alert"]), self.appkey, ) self.add_to_log("%s notification" % self.appname, logmessage) except Exception as ex: import traceback traceback.print_exc() self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex)))