def notify_user(user, data_message=None): from pyfcm import FCMNotification push_service = FCMNotification( api_key="AAAA19KbT04:APA91bFroH6rGfC-eywj49abV2OZMyVj-St1v7eOhwSADPKG0Fon8tfwVxMRYlcIYOkHf8xEqnqlpbIuqU7W3oF9" + "LhxiDjLlKw4BoXaIknY75t1rBDZTP5OzY6iYz_MJF2FGAadmoqT_") registration_id = user.prof.token if registration_id is not None: push_service.single_device_data_message(registration_id=registration_id, data_message=data_message)
def send_fcm_notification(title="", body="", data=None, users=None): """ sends fcm notification to a single or multiple user device :param title: title of the notification message :param body: body of the notification :param data: any data to be sent :param users: list of user ids :return: True/False """ if users: push_service = FCMNotification(api_key=settings.FCM_API_KEY) try: if data: if isinstance(users, list): registration_ids = [ devices.registration_id for devices in UserDevice.objects.filter( used_id__in=users) ] push_service.multiple_devices_data_message( registration_ids=registration_ids, data_message=data) else: registration_id = UserDevice.objects.get( user_id=users).registration_id push_service.single_device_data_message( registration_id=registration_id, data_message=data) else: if isinstance(users, list): registration_ids = [ devices.registration_id for devices in UserDevice.objects.filter( user_id__in=users) ] push_service.notify_multiple_devices( registration_ids=registration_ids, message_title=title, message_body=body) else: registration_id = UserDevice.objects.get( user_id=users).registration_id push_service.notify_single_device( registration_id=registration_id, message_title=title, message_body=body) return True except: return False else: return False
def push_notify_annoc(token, mt, text): global mykey push_service = FCMNotification(api_key=mykey) data_message = {"mod": "1", "title": mt, "text": text} result = push_service.single_device_data_message(registration_id=token, data_message=data_message)
def sendDataMessage(self, device_id="", message_body=None, api_key=os.getenv('firebase_landslide_serverkey')): push_service = FCMNotification(api_key=api_key) registration_id = device_id datamsg = {"data": message_body} if registration_id == "" or registration_id is None: return 0 else: result = push_service.single_device_data_message( registration_id=registration_id, data_message=datamsg) return result['success']
def send_notify_single(device_id, title, message, action, payload): push_service = FCMNotification(api_key=API_KEY) registration_id = device_id data_message = { "title": title, "message": message, "action": action, "payload": payload } # To a single device result = push_service.single_device_data_message( registration_id=registration_id, data_message=data_message) print(result) return result
class SMS: def __init__(self): self.client = FCMNotification(settings.FIREBASE_TOKEN) def wait_for_status_change(self, schedule) -> bool: start_time = datetime.now() timeout = settings.SMS_TIMEOUT status_changed = False while not status_changed: schedule.refresh_from_db() if schedule.notification_status != 0: status_changed = True if (datetime.now() - start_time).total_seconds() >= timeout: schedule.notification_status = 3 schedule.save() raise SMSTimeoutError('Tempo excedido') sleep(1) return True def send_message(self, schedule_id): from app.schedule.models import Schedule schedule = Schedule.objects.get(pk=schedule_id) phone = f'+55{schedule.patient.phone}' try: self.client.single_device_data_message( schedule.dentist.device_token, data_message={ 'sendTo': phone, 'content': schedule.get_message(), 'scheduleId': schedule.id }) return True except: return False
def push_notify_to_one(registration_id, mt, mb, code, userID, roomType): global mykey push_service = FCMNotification(api_key=mykey) data_message = { "mod": "0", "msgTitle": mt, "msgText": mb, "code": code, "userID": userID, "roomType": roomType } result = push_service.single_device_data_message( registration_id=registration_id, data_message=data_message)
def fcm_send_single_device_data_message(registration_id, condition=None, collapse_key=None, delay_while_idle=False, time_to_live=None, restricted_package_name=None, low_priority=False, dry_run=False, data_message=None, content_available=None, api_key=None, timeout=5, json_encoder=None): """ Send push message to a single device All arguments correspond to that defined in pyfcm/fcm.py. Args: registration_id (str): FCM device registration IDs. data_message (dict): Data message payload to send alone or with the notification message Keyword Args: collapse_key (str, optional): Identifier for a group of messages that can be collapsed so that only the last message gets sent when delivery can be resumed. Defaults to ``None``. delay_while_idle (bool, optional): If ``True`` indicates that the message should not be sent until the device becomes active. time_to_live (int, optional): How long (in seconds) the message should be kept in FCM storage if the device is offline. The maximum time to live supported is 4 weeks. Defaults to ``None`` which uses the FCM default of 4 weeks. low_priority (boolean, optional): Whether to send notification with the low priority flag. Defaults to ``False``. restricted_package_name (str, optional): Package name of the application where the registration IDs must match in order to receive the message. Defaults to ``None``. dry_run (bool, optional): If ``True`` no message will be sent but request will be tested. timeout (int, optional): set time limit for the request Returns: :dict:`multicast_id(long), success(int), failure(int), canonical_ids(int), results(list)`: Response from FCM server. Raises: AuthenticationError: If :attr:`api_key` is not set or provided or there is an error authenticating the sender. FCMServerError: Internal server error or timeout error on Firebase cloud messaging server InvalidDataError: Invalid data provided InternalPackageError: Mostly from changes in the response of FCM, contact the project owner to resolve the issue """ push_service = FCMNotification( api_key=SETTINGS.get("FCM_SERVER_KEY") if api_key is None else api_key, json_encoder=json_encoder, ) return push_service.single_device_data_message( registration_id=registration_id, condition=condition, collapse_key=collapse_key, delay_while_idle=delay_while_idle, time_to_live=time_to_live, restricted_package_name=restricted_package_name, low_priority=low_priority, dry_run=dry_run, data_message=data_message, content_available=content_available, timeout=timeout)
# FCM Notification을 위한 모듈. 원랜 firebase 측으로 HTTP request를 전송해야 하지만 # 어떤 개발자가 이게 불편하다고 느꼈는지 pyfcm을 만들어 두었다 fcm = FCMNotification(api_key='') # FCM 서버 키를 통해 객체를 만들자 # 클라이언트 하나에 보내기, 여러 곳에 보내기, topic subscriber에 보내기가 대표적인 메소드다 fcm.notify_single_device(registration_id='', message_title='제목이야', message_body='body다') fcm.notify_multiple_devices(registration_ids=['', ''], message_title='제-목', message_body='배고파') # 여러 클라이언트에 보내는 메소드. registration_ids 파라미터로 리스트 형태의 클라이언트 키들을 전달한다 fcm.notify_topic_subscribers(topic_name='', message_title='제-목', message_body='body!') # 특정 topic을 subscribe하고 있는 디바이스에 보내기 # fcm 푸쉬 메시지는 data message를 전송할 수 있다. 일반적으로 JSON이며 pyfcm 측에서는 data_message 인자로 딕셔너리를 전달하면 알아서 직렬화 처리해준다 data = {'key1': 123, 'key2': 1234} fcm.notify_single_device(registration_id='', data_message=data) # notify_*** 메소드에도 data_message 파라미터가 있지만, pyfcm 측에서 data messaging을 위한 메소드를 만들어 두었다 fcm.single_device_data_message(registration_id='', data_message=data) fcm.multiple_devices_data_message(registration_ids=['', '', ''], data_message=data)
class Helpers: def __init__(self, flask_app): self.logger = flask_app.logger apikey = "AAAAgOfyS6s:APA91bH0GGnd4Xvw_pWMDpGmsQrR79CU8_bOmDj2QsHyrpua89dwV_UUAcJNRELByd_uikq4Hd5oI-ik6uWoW9i4w3qgtdqqg8TYKwwhAg-HllaBKoIdAy9yF1tvIGaAUvXGLtdIzTqF" # api key from FCM for the app self.push_service = FCMNotification(api_key=apikey) self.STATUS_YES = 'Y' self.STATUS_NO = 'N' self.all_days = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ] self.config = json.load(open(CONFIG_PATH)) self.client_id = self.get_config('basic', 'client_id') def get_config(self, *args): ret = self.config for i in range(len(args)): ret = ret[args[i]] return ret def build_url(self, addr, *args): ''' :param addr: Address :param args: list of components in the url. Will be appended with '/' :return: returns the formatted url ''' comp = '' for i in range(len(args) - 1): comp += args[i] + '/' comp += args[len(args) - 1] url = urllib.parse.urljoin("http://" + addr, comp) logger.debug('Built url : ', url) return url def get_request(self, url, data=None): ''' :param url: url to send the get request :param params: params to append to the query :return: response from the server ''' response = None try: self.logger.debug('GET request : %s', url) params = json.dumps(data) self.logger.debug(str(params)) response = requests.get(url, params=params) except Exception as e: print(e) return response def query_installs(self, request, cur_session): ''' queries Install table according to all ids supplied in request object :param request: current request context :param cur_session: current database session object :returns: List of matching entries if present, None otherwise ''' u_id = self.read_user_id(request.args.get('u_id', None)) i_id = request.args.get('i_id', None) p_id = request.args.get('p_id', None) return self.get_all_installs(cur_session, u_id, i_id, p_id) def get_all_installs(self, cur_session, u_id=None, i_id=None, p_id=None): if i_id is None and p_id is None and u_id is None: return None if i_id is not None: cur_installs = cur_session.query(Install).filter( Install.install_id == i_id).all() elif u_id is not None: cur_installs = cur_session.query(Install).filter( Install.user_id == u_id).all() else: cur_installs = cur_session.query(Install).filter( Install.push_id == p_id).all() if len(cur_installs) == 0: return None return cur_installs def get_all_medications(self, cur_session, m_id=None, m_name=None, u_id=None, d_id=None): if m_id is None and u_id is None and d_id is None and m_name is None: return None if m_id is not None: cur_meds = cur_session.query(Medication).filter( Medication.med_id == m_id).all() elif u_id is not None: cur_meds = cur_session.query(Medication).filter( Medication.user_id == u_id).all() elif m_name is not None: cur_meds = cur_session.query(Medication).filter( Medication.med_name == m_name).all() else: cur_meds = cur_session.query(Medication).filter( Medication.dosage_id == d_id).all() if len(cur_meds) == 0: return None return cur_meds def keygen(self, cur_session, cur_table, table_attr): key = np.random.randint(0, 2**31) prev_entry = cur_session.query(cur_table).filter( table_attr == key).first() if prev_entry is not None: return self.keygen(cur_session, cur_table, table_attr) return key def stringify(self, lst): ret = '' for s in lst: if len(s) == 0: continue ret += ',' + s return ret[1:] def send_push_notification(self, reg_id_list, data_message=None): ''' : param reg_id_list: list of registration ids : param data_message: optional payload with custom key-value pairs : returns: Sends out push notification to multiple devices.response data from pyFCM ''' if len(reg_id_list) == 0: self.logger.debug( 'No registration ids to send push notification to') return if len(reg_id_list) == 1: self.logger.debug('Making call to FCM for single Data Message...') try: result = self.push_service.single_device_data_message( registration_id=reg_id_list[0], data_message=data_message) except Exception as e: self.logger.debug(e) return None else: self.logger.debug( 'Making call to FCM for multiple Data Messages...') try: result = self.push_service.multiple_devices_data_message( registration_ids=reg_id_list, data_message=data_message) except Exception as e: self.logger.debug(e) return None return result # Is there a better way to do this? def get_clean_data_array(self, shape): # ret = np.empty(shape, dtype=object) # This has problems : https://stackoverflow.com/questions/33983053/how-to-create-a-numpy-array-of-lists # ret.fill([]) ''' IMPORTANT! The first element (index 0) will be None. Use lists starting from 1 ''' linear_size = 1 for s in shape: linear_size *= s ret = np.empty((linear_size, ), dtype=object) for i, v in enumerate(ret): ret[i] = list([]) # finally, reshape the matrix ret = ret.reshape(shape) return ret def read_user_id(self, u_id): if u_id is None or u_id == '': return '' algorithm = sha2() algorithm.update(u_id.encode()) return algorithm.hexdigest().upper() def validate_intakes(self, med, dose, cur_session): # Oh boy... validation_date = parser.parse(med.validation_date) start_date = validation_date + timedelta(days=1) med.validation_date = (datetime.now() - timedelta(days=1)).isoformat() intakes = cur_session.query(Intake).filter( Intake.med_id == med.med_id).filter( Intake.planned_date > validation_date).all() ideal_intake_dates = self.get_ideal_intake_dates(dose, start_date) intake_dates_present = set( [parser.parse(x.planned_date) for x in intakes]) missed_intake_dates = [ x for x in ideal_intake_dates if x not in intake_dates_present ] missed_intakes = [ Intake(med_id=med.med_id, planned_date=x.isoformat(), intake_status=3) for x in missed_intake_dates ] cur_session.add_all(missed_intakes) cur_session.commit() def get_ideal_intake_dates(self, dose, start_date): ideal_intakes = [] def get_prev_dosage_date(days, cur_date): cur_day_idx = cur_date.weekday() prev_day_idx = -1 for i in range(len(days) - 1, -1, -1): if days[i] < cur_day_idx: prev_day_idx = i break prev_day_delta = (cur_day_idx - days[prev_day_idx] + 7) % 7 td = timedelta(days=prev_day_delta) return cur_date - td dosage_days = [self.all_days.index(x) for x in dose.get_days()] ideal_times = [ get_prev_dosage_date(dosage_days, parser.parse(tim)) for tim in dose.get_times() ] ideal_times.reverse() while ideal_times[0].date() >= start_date.date(): ideal_intakes.extend(ideal_times) ideal_times = [ get_prev_dosage_date(dosage_days, tim) for tim in ideal_times ] return reversed(ideal_intakes) def get_intake_status(self, planned_date, actual_date): p_date = parser.parse(planned_date) a_date = parser.parse(actual_date) delta = time.mktime(a_date.utctimetuple()) - time.mktime( p_date.utctimetuple()) four_hours = 1000 * 60 * 60 * 4 if delta < 0: return 1 elif delta > four_hours: return 2 return 0
def FCMSend(reg_id, data): server_key = 'AAAAbJRUy5U:APA91bHXw43Jlye_Cthdd_dXVnLLYE9oKNjFt-z8BpYeEPFIVCcP2P_tnsdTY8VooqJEL5rREMk0UWJ1B4W5Xy-dbaLKc88C_g88VAnYjjEjviDOOts7AJ0Lgp_lC_PTlQNh2_5qfwJJ' push_service = FCMNotification(api_key=server_key) return push_service.single_device_data_message(registration_id=reg_id, data_message=data)
class APICall: def __init__(self, app, request, requiredParams=[]): self._uid = None self._config = {} self.params = {} self._app = app self._request = request self._readConfigFile() self._enableLogging() self._pushService = FCMNotification( api_key= "AAAAJcqwb2M:APA91bFixpCKO1fE6kObLma1upi1RBPWHNMufAFhz2CzycG2oqfELoh7vLZ8ceGCpYxiDuClCnsD9eJp1BgMkl2FI97996JC4vAqZMuO_HF7VHBEYFIPUuhvlRQ2KuKlMsrSYwgdjZ1Y" ) self._userColumns = [ "deviceNotificationToken", "phoneNumber", "name", "email", "birthYear", "gender", "relationshipStatus", "thumbnail" ] self._maxFriends = 20 if not self._getRequestParams(requiredParams): abort(400) if not self._connectDB(): abort(500) self._checkAuth() def __del__(self): self._closeDB() def _readConfigFile(self): global _g_configFile try: with open(_g_configFile) as inpf: self._config = json.load(inpf) except Exception as e: self._app.logger.error( "Caught exception reading the config file '{}': {}".format( _g_configFile, e)) abort(500) if ("logging" not in self._config or "database" not in self._config): self._app.logger.error( "Config file '{}' missing required section.".format( _g_configFile)) abort(500) def _enableLogging(self): if (("started" in self._config["logging"] and self._config["logging"]["started"]) or self._app.debug): return handler = FileHandler(self._config["logging"]["logfile"]) handler.setFormatter( Formatter( '%(asctime)s %(levelname)s line=%(lineno)d - %(message)s')) handler.setLevel(self._config["logging"]["level"]) self._app.logger.addHandler(handler) self._config["logging"]["started"] = True def _getRequestParams(self, requiredParams): requestParams = self._request.values if len( self._request.values) > 0 else self._request.get_json() for param in requiredParams: if param not in requestParams: return False for param in requestParams: self.params[param] = requestParams[param] return True def _encodeAuthToken(self): assert (self._uid) payload = { 'iat': datetime.datetime.utcnow(), 'exp': datetime.datetime.utcnow() + datetime.timedelta( days=self._config.get("auth-token-expiration-days", 365.25)), 'sub': self._uid } return jwt.encode(payload, self._config['token-key'], algorithm='HS256') def _decodeAuthToken(self): authHeader = self._request.headers.get('Authorization') if not authHeader: abort(403) try: return jwt.decode(authHeader.split()[1], self._config['token-key'])['sub'] except jwt.ExpiredSignatureError: abort(401 ) # TODO: response should use WWW-Authenticate header field except jwt.InvalidTokenError: abort(403) def _checkAuth(self): if "Authorization" not in self._request.headers: if self._request.path != "/userInfo": abort(401) # TAI: check app key here? return self._uid = self._decodeAuthToken() if not self._uid or not (isinstance(self._uid, int) or self._uid.isdigit()): abort(401) def _connectDB(self): if "optionalSocket" in self._config["database"]: self._db = MySQLdb.connect(self._config["database"]["server"], \ self._config["database"]["user"], \ self._config["database"]["password"], \ self._config["database"]["name"], \ unix_socket=self._config["database"]["optionalSocket"]) else: self._db = MySQLdb.connect(self._config["database"]["server"], \ self._config["database"]["user"], \ self._config["database"]["password"], \ self._config["database"]["name"]) return self._db is not None def _closeDB(self): if self._db: self._db.close() self._db = None def _pushNotification(self, deviceToken, payload): return self._pushService.single_device_data_message( registration_id=deviceToken, data_message=payload) def apihandler(fn): @wraps(fn) def decorated(*args, **kwargs): try: return fn(*args, **kwargs) except HTTPException as he: raise except Exception as e: args[0]._app.logger.error( "Caught unexpected exception in api handler: {}".format( e)) abort(500) finally: args[0]._closeDB() return decorated def _uidFromPhoneNum(self, phoneNum): cursor = self._db.cursor() cursor.execute("SELECT userId FROM User WHERE phoneNumber = %s", (phoneNum, )) ur = cursor.fetchone() return ur[0] if ur else None @apihandler def getUserInfo(self): cursor = self._db.cursor(MySQLdb.cursors.DictCursor) cursor.execute( "SELECT phoneNumber, name, email, birthYear, gender, relationshipStatus, thumbnail FROM User WHERE userId = %s", (self._uid, )) user = cursor.fetchone() if not user: abort(500) return make_response(jsonify(user), 200) @apihandler def setUserInfo(self): queryParams = [] if self._uid: sql = "UPDATE User SET " for paramKey, paramVal in self.params.items(): if paramKey in self._userColumns: if queryParams: sql += ", " sql += "{} = %s".format(paramKey) queryParams.append(paramVal) if not queryParams: abort(400) sql += " WHERE userId = %s" queryParams.append(self._uid) resultMsg = "successfully updated user info" self._app.logger.info("updating user {} with: {}".format( self._uid, queryParams)) # TODO: notify friends if thumbnail and/or phoneNumber changed else: requiredColumns = [ "deviceNotificationToken", "phoneNumber", "name", "email" ] sql = "INSERT INTO User ({}) VALUES(%s{})".format( ",".join(self._userColumns), ", %s" * (len(self._userColumns) - 1)) for col in self._userColumns: paramVal = self.params.get(col, None) if paramVal and col in requiredColumns: requiredColumns.remove(col) queryParams.append(paramVal) if len(requiredColumns) > 0: self._app.logger.error( "adding new user missing required field(s): {}".format( requiredColumns)) abort(400) if self._uidFromPhoneNum(self.params["phoneNumber"]): self._app.logger.warning( "tried to add duplicate phoneNumber: {}".format( self.params["phoneNumber"])) return make_response(jsonify({"message": "duplicate"}), 403) resultMsg = "successfully registered new user" self._app.logger.info( "adding new user with: {}".format(queryParams)) cursor = self._db.cursor() try: cursor.execute(sql, queryParams) self._db.commit() except Exception as e: self._db.rollback() raise if self._uid: return make_response( jsonify({ "message": resultMsg, "userId": self._uid }), 200) self._uid = self._uidFromPhoneNum(self.params["phoneNumber"]) authToken = self._encodeAuthToken() return make_response( jsonify({ "message": resultMsg, "userId": self._uid, "authToken": authToken.decode() }), 200) @apihandler def setStatus(self): free = self.params.get("free", False) if not free: abort(400) self._app.logger.info("user {} set free status".format(self._uid)) insertCursor = self._db.cursor() try: nowstr = datetime.datetime.utcnow().strftime("%Y-%m-%d %H-%M-%S") insertCursor.execute( "INSERT INTO FreeLog (userId, timestamp) VALUES(%s, %s)", (self._uid, nowstr)) self._db.commit() except Exception as e: self._db.rollback() raise friendCursor = self._db.cursor() sql = """SELECT FL.userId, U.deviceNotificationToken FROM FreeLog AS FL INNER JOIN User AS U ON FL.userId = U.userId INNER JOIN Friend AS FF1 ON FL.userId = FF1.userId1 INNER JOIN Friend AS FF2 ON FL.userId = FF2.userId2 WHERE FF1.userId2 = %s AND FF2.userId1 = %s AND FL.timestamp > %s""" timestr = (datetime.datetime.utcnow() + datetime.timedelta(hours=-12)).strftime("%Y-%m-%d %H-%M-%S") friendCursor.execute(sql, (self._uid, self._uid, timestr)) friends = [] for friend in friendCursor.fetchall(): friends.append(friend[0]) self._pushNotification(friend[1], { "type": "friendFree", "userId": self._uid }) return make_response(jsonify(friends), 200) def _friendCount(self): cursor = self._db.cursor() cursor.execute( "SELECT COUNT(*) FROM Friend WHERE userId1 = %s OR userId2= %s", (self._uid, self._uid)) return cursor.fetchone()[0] def _removeFriend(self, friendUid, friendDeviceToken): nowstr = datetime.datetime.utcnow().strftime("%Y-%m-%d %H-%M-%S") cursor = self._db.cursor() try: cursor.execute( "UPDATE Friend SET timeEnded = %s WHERE timeEnded IS NULL AND ((userId1 = %s AND userId2 = %s) OR (userId1 = %s AND userId2 = %s))", (nowstr, self._uid, friendUid, friendUid, self._uid)) self._db.commit() self._pushNotification(friendDeviceToken, { "type": "removeFriend", "userId": self._uid }) except Exception as e: self._db.rollback() raise def _promoteFriendReq(self, friendUid): nowstr = datetime.datetime.utcnow().strftime("%Y-%m-%d %H-%M-%S") try: cursor = self._db.cursor() cursor.execute( "INSERT INTO Friend (userId1, userId2, timeStarted, timeEnded) VALUES(%s, %s, %s, %s)", (friendUid, self._uid, nowstr, None)) cursor.execute( "DELETE FROM FriendRequest WHERE sourceUserId = %s AND targetUserId = %s", (friendUid, self._uid)) self._db.commit() except Exception as e: self._db.rollback() raise def _addFriendReq(self, friendUid): cursor = self._db.cursor() cursor.execute( "SELECT * FROM FriendRequest WHERE sourceUserId = %s AND targetUserId = %s", (self._uid, friendUid)) existingFriendReq = cursor.fetchone() nowstr = datetime.datetime.utcnow().strftime("%Y-%m-%d %H-%M-%S") if existingFriendReq: sql = "UPDATE FriendRequest SET timestamp = %s WHERE sourceUserId = %s AND targetUserId = %s" queryParams = (nowstr, self._uid, friendUid) else: sql = "INSERT INTO FriendRequest (sourceUserId, targetUserId, timestamp) VALUES(%s, %s, %s)" queryParams = (self._uid, friendUid, nowstr) cursor = self._db.cursor() try: cursor.execute(sql, queryParams) self._db.commit() except Exception as e: self._db.rollback() raise return (nowstr, existingFriendReq is None) def _notifyFriendRequest(self, reqType, friendDeviceToken, requestedTimestamp, repeat=False): cursor = self._db.cursor() cursor.execute( "SELECT phoneNumber, name, thumbnail FROM User WHERE userId = %s", (self._uid, )) user = cursor.fetchone() assert (user) if reqType == "friendRequest": msg = self.params.get( "message", "{} suggested you become Veni friends.".format(user[1])) else: msg = "{} accepted friend request.".format(user[1]) friendPayload = { "type": reqType, "message": msg, "userId": self._uid, "phoneNumber": user[0], "name": user[1], "thumbnail": user[2] } if requestedTimestamp and isinstance(requestedTimestamp, datetime.datetime): friendPayload["requestedTimestamp"] = requestedTimestamp.strftime( "%Y-%m-%d %H-%M-S") else: friendPayload["requestedTimestamp"] = requestedTimestamp if repeat: friendPayload["repeat"] = True self._pushNotification(friendDeviceToken, friendPayload) # TODO: auto-expiring friends requires push notification --> use a separate script @apihandler def addFriend(self): if self._friendCount() >= self._maxFriends: self._app.logger.info( "user {} tried to add too many friends".format(self._uid)) abort(403) cursor = self._db.cursor() cursor.execute( "SELECT userId, deviceNotificationToken, phoneNumber, name, thumbnail FROM User WHERE phoneNumber = %s", (self.params["friendPhoneNumber"], )) friendUser = cursor.fetchone() if not friendUser: self._app.logger.warning( "user {} tried to add friend with unknown phoneNumber={}". format(self._uid, self.params["friendPhoneNumber"])) abort(404) if "remove" in self.params: self._app.logger.info("user {} removing friend {}".format( self._uid, friendUser[0])) self._removeFriend(friendUser[0], friendUser[1]) return make_response( jsonify({"message": "successfully removed friend"}), 200) cursor = self._db.cursor() cursor.execute( "SELECT timestamp FROM FriendRequest WHERE sourceUserId = %s AND targetUserId = %s", (friendUser[0], self._uid)) friendReq = cursor.fetchone() if friendReq: self._app.logger.info( "user {} accepted friend request from {}".format( self._uid, friendUser[0])) self._promoteFriendReq(friendUser[0]) self._notifyFriendRequest("friendAccepted", friendUser[1], friendReq[0]) return make_response( jsonify({ "friend": { "userId": friendUser[0], "phoneNumber": friendUser[2], "name": friendUser[3], "thumbnail": friendUser[4] } }), 200) else: self._app.logger.info("user {} friend request to {}".format( self._uid, friendUser[0])) requestedTimestamp, newReq = self._addFriendReq(friendUser[0]) self._notifyFriendRequest("friendRequest", friendUser[1], requestedTimestamp, not newReq) return make_response(jsonify({"message": "sent friend request"}), 202) @apihandler def contactFriend(self): self._app.logger.info("user {} contacting {}".format( self._uid, self.params["friendUserId"])) sql = "INSERT INTO ContactLog (sourceUserId, targetUserId, timestamp) VALUES (%s, %s, %s)" cursor = self._db.cursor() try: nowstr = datetime.datetime.utcnow().strftime("%Y-%m-%d %H-%M-%S") cursor.execute(sql, (self._uid, self.params["friendUserId"], nowstr)) self._db.commit() except Exception as e: self._db.rollback() raise return make_response(jsonify({"message": "contact attempt logged"}), 200)
def fcm_send_single_device_data_message( registration_id, condition=None, collapse_key=None, delay_while_idle=False, time_to_live=None, restricted_package_name=None, low_priority=False, dry_run=False, data_message=None, content_available=None, api_key=None, timeout=5, json_encoder=None): """ Send push message to a single device All arguments correspond to that defined in pyfcm/fcm.py. Args: registration_id (str): FCM device registration IDs. data_message (dict): Data message payload to send alone or with the notification message Keyword Args: collapse_key (str, optional): Identifier for a group of messages that can be collapsed so that only the last message gets sent when delivery can be resumed. Defaults to ``None``. delay_while_idle (bool, optional): If ``True`` indicates that the message should not be sent until the device becomes active. time_to_live (int, optional): How long (in seconds) the message should be kept in FCM storage if the device is offline. The maximum time to live supported is 4 weeks. Defaults to ``None`` which uses the FCM default of 4 weeks. low_priority (boolean, optional): Whether to send notification with the low priority flag. Defaults to ``False``. restricted_package_name (str, optional): Package name of the application where the registration IDs must match in order to receive the message. Defaults to ``None``. dry_run (bool, optional): If ``True`` no message will be sent but request will be tested. timeout (int, optional): set time limit for the request Returns: :dict:`multicast_id(long), success(int), failure(int), canonical_ids(int), results(list)`: Response from FCM server. Raises: AuthenticationError: If :attr:`api_key` is not set or provided or there is an error authenticating the sender. FCMServerError: Internal server error or timeout error on Firebase cloud messaging server InvalidDataError: Invalid data provided InternalPackageError: Mostly from changes in the response of FCM, contact the project owner to resolve the issue """ push_service = FCMNotification( api_key=SETTINGS.get("FCM_SERVER_KEY") if api_key is None else api_key, json_encoder=json_encoder, ) return push_service.single_device_data_message( registration_id=registration_id, condition=condition, collapse_key=collapse_key, delay_while_idle=delay_while_idle, time_to_live=time_to_live, restricted_package_name=restricted_package_name, low_priority=low_priority, dry_run=dry_run, data_message=data_message, content_available=content_available, timeout=timeout )
from pyfcm import FCMNotification push_service = FCMNotification( api_key= "AAAAJTNYVvo:APA91bGMFBpgLfDzMqsji42jiudHeYP_xTvmO_-KGVMHJWp9lugsKIx2Eb5AM3peoguak_Y-EPbmqA86u13WvxiKqIBGkUtrbWjUgs7qBXjzPIu2s07IJ4-OIaPCWwLSupVd_t-acLVM" ) # Your api-key can be gotten from: https://console.firebase.google.com/project/<project-name>/settings/cloudmessaging registration_id = "eOoXzmclKUEImb2nQLxlDj:APA91bEVJiCOh5vGYLRSD454AVE5bbk7eWRLjZp1uABHJ08wsxvcWB3Ws_eTldEcDS-CJSuWCWQvYplvDGup_BYrKoK6TF7rinKb1pksRfVwYFFExYONO6NK5uGro1mkoDqsQgUijwf-" # payload = {"key":"Hi Mubashir, your customized news for today is ready"} data_message = { "Nick": "Mario", "body": "great match!", "Room": "PortugalVSDenmark" } message_title = "Hello" # result = push_service.notify_single_device(low_priority=False,registration_id=registration_id, message_title=message_title, data_message=message_body) result = push_service.single_device_data_message( registration_id=registration_id, low_priority=False, data_message=data_message) print(result)
logging.warn("%s: old notification not acknowledged, not re-sending", token) else: logging.warn("iOS push not configured but iOS source requested") else: logging.warn("unknown source type %s" % source) else: if ios_onscreen: # rain has stopped and the notification is (possibly) still # displayed on the device. if source == "ios": try: apns.send_message(token, None, badge=0, content_available=True, extra={"clear_all": True}) except BadDeviceToken: logging.warn("%s: silent iOS notification failed with BadDeviceToken, removing push client", token) collection.remove(doc_id) except Unregistered: logging.warn("%s: silent iOS notification failed with Unregistered, removing push client", token) collection.remove(doc_id) else: logging.warn("%s: sent silent notification" % token) collection.update({"_id": doc_id}, { "$set": {"ios_onscreen": False} }) elif source == "android": result = fcm.single_device_data_message(registration_id=token, data_message={"clear_all": True}) logging.warn("%s: Delivered android data push with result=%s" % (token, result)) collection.update({"_id": doc_id}, { "$set": {"ios_onscreen": False} }) else: logging.error("%s: Unsupported source" % token) cnt = cnt + 1 logging.warn("===> Processed %d total clients" % cnt)
GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(Button, GPIO.IN) GPIO.setup(LED_B, GPIO.OUT) GPIO.output(LED_B, True) ################################ print 'Start' print "ring the door bell" while True: if GPIO.input(Button) == 0: door_bell_on = 1 #on result = push_service.single_device_data_message( registration_id=registration_id, data_message=data_message) print result os.system("mpg321 doorbell_sound.mp3" ) #doorbell sound on & need doorbell_sound.mp3 while True: try: print '0,1 Waiting for connection' #if 'yes' signal from android c_response, addr = server_socket.accept() print '...connected from :', addr confirm_data = '' confirm_data = c_response.recv(BUFSIZE) #except timeout: # pass
def firebase(registrationId, dataMessage): push_service = FCMNotification(api_key="AIzaSyDNvYj9Is5cOkuH7XJCRqW1zcMxOx2azr0") registrationID = registrationId dataMessage = dataMessage result = push_service.single_device_data_message(registration_id=registrationID, data_message=dataMessage)
def single_device_data_message(registration_id: str, data_message: dict, **kwargs): push_service = FCMNotification(api_key=settings.FCM_API_KEY) return push_service.single_device_data_message( registration_id=registration_id, data_message=data_message, **kwargs)