def send_messages(self, request, queryset, bulk=False): """ Provides error handling for DeviceAdmin send_message and send_bulk_message methods. """ total_failure = 0 single_responses: List[Tuple[SendResponse, str]] = [] for device in queryset: device: "FCMDevice" if bulk: response = queryset.send_message( Message(notification=Notification( title="Test notification", body="Test bulk notification"))) total_failure = len(response.deactivated_registration_ids) return self._send_deactivated_message(request, response, total_failure, False) else: response = device.send_message( Message(notification=Notification( title="Test notification", body="Test single notification"))) single_responses.append((response, device.registration_id)) if type(response) != SendResponse: total_failure += 1 self._send_deactivated_message(request, single_responses, total_failure, False)
def send_push_notification( participant: Participant, reference_schedule: ScheduledEvent, survey_obj_ids: List[str], fcm_token: str ): """ Contains the body of the code to send a notification """ # we include a nonce in case of notification deduplication. data_kwargs = { 'nonce': ''.join(random.choice(OBJECT_ID_ALLOWED_CHARS) for _ in range(32)), 'sent_time': reference_schedule.scheduled_time.strftime(API_TIME_FORMAT), 'type': 'survey', 'survey_ids': json.dumps(list(set(survey_obj_ids))), # Dedupe. } if participant.os_type == Participant.ANDROID_API: message = Message( android=AndroidConfig(data=data_kwargs, priority='high'), token=fcm_token, ) else: display_message = \ "You have a survey to take." if len(survey_obj_ids) == 1 else "You have surveys to take." message = Message( data=data_kwargs, token=fcm_token, notification=Notification(title="Beiwe", body=display_message), ) send_notification(message)
def notify_getoff(): fcm_messages = [] standing_users = {} vacancies_created_car_ids = set() itinerary_keys = redis.keys("itinerary:*") for itinerary_key in itinerary_keys: user_id = itinerary_key.split(':')[-1] user = get_user(user_id) itinerary = get_itinerary(user_id) train = get_train(itinerary['subway_id'], itinerary['train_id']) car_id = f"{train.subway_id}-{train.number}-{itinerary['car_number']}" if train.station_id == itinerary['destination_id']: delete_itinerary(user_id) vacancies_created_car_ids.add(car_id) if user_id.startswith('dummy'): continue # send notification to users who need to get off the train if user.get('notification_itinerary_end', 'on') == 'on' and user['platform'] == 'fcm': message = Message( notification=Notification('여정이 끝났습니다!', '하차하세요~'), token=user['token'], ) fcm_messages.append(message) else: # collect real users who are standing and whose itinerary is ongoing if user_id.startswith('dummy'): continue if itinerary['seated'] == "false": if car_id not in standing_users: standing_users[car_id] = [] standing_users[car_id].append(user) for car_id in vacancies_created_car_ids: if car_id in standing_users: for user in standing_users[car_id]: if user.get('notification_seat_vacancy', 'on') == 'on' and user['platform'] == 'fcm': message = Message( notification=Notification('자리가 생겼습니다!', '착석하세요~'), token=user['token'], ) fcm_messages.append(message) # bulk send FCM messages messaging.send_all(fcm_messages) for m in fcm_messages: click.echo(f"token: {m.token} title: {m.notification.title} body: {m.notification.body}") click.echo(f"[{datetime.now()}] {len(fcm_messages)} 개 FCM 알람 발송")
def send_to_device(msg, mobile_device): if not firebase_app: return if mobile_device.platform == 'ios': ios_push_notification(msg, mobile_device.device_token) return try: message = Message(data=msg, android=AndroidConfig(priority='high'), apns=APNSConfig(headers={ 'apns-push-type': 'background', 'apns-priority': '5' }, payload=APNSPayload(aps=Aps( content_available=True))), token=mobile_device.device_token) return send(message, app=firebase_app) except (UnregisteredError, SenderIdMismatchError, firebase_admin.exceptions.InternalError): MobileDevice.objects.filter( device_token=mobile_device.device_token).update( deactivated_at=now()) except: import traceback traceback.print_exc() sentryClient.captureException()
def send_message( self, message: messaging.Message, **more_send_message_kwargs, ) -> Union[Optional[messaging.SendResponse], FirebaseError]: """ Send single message. The message's token should be blank (and will be overridden if not). Responds with message ID string. :param message: firebase.messaging.Message. If `message` includes a token/id, it will be overridden. :param more_send_message_kwargs: Parameters for firebase.messaging.send_all() - dry_run: bool. Whether to actually send the notification to the device - app: firebase_admin.App. Specify a specific app to use If there are any new parameters, you can still specify them here. :raises FirebaseError :returns messaging.SendResponse or FirebaseError if the device was deactivated due to an error. """ message.token = self.registration_id try: return messaging.SendResponse( {"name": messaging.send(message, **more_send_message_kwargs)}, None) except FirebaseError as e: self.deactivate_devices_with_error_result(self.registration_id, e) return e
def send_to_device(registration_token, msg): message = Message( data=msg, android=AndroidConfig(priority="high"), apns=APNSConfig(payload=APNSPayload(aps=Aps(content_available=True))), token=registration_token) return send(message)
def send_to_topic(topic_name, session_shared, session_documents, user_id=""): """ Sends a new message to an existing FirebaseMessaging topic """ topic = topic_name message = Message( data={ 'session_id': topic_name, 'session_shared': session_shared, 'session_documents': json.dumps(session_documents), 'user_id': user_id, }, topic=topic, ) response = send(message) return
def send_to_device(msg, device_token): try: message = Message(data=msg, android=AndroidConfig(priority='high'), apns=APNSConfig(headers={ 'apns-push-type': 'background', 'apns-priority': '5' }, payload=APNSPayload(aps=Aps( content_available=True))), token=device_token) return send(message) except UnregisteredError: MobileDevice.objects.filter(device_token=device_token).update( deactivated_at=now())
def ios_push_notification(data, device_token): if not firebase_app: return # TODO: Fixed notification settings that only sends events turned on by default, until we find a better solution for ios if data['type'] in [ 'heaterEvent', ]: return if data['type'] == 'printEvent' and data['eventType'] not in [ 'PrintDone', 'PrintCancelled' ]: return notification = Notification(title=data['title'], body=data['body']) if data.get('picUrl'): notification.image = data.get('picUrl') try: message = Message(notification=notification, apns=APNSConfig(headers={ 'apns-push-type': 'alert', 'apns-priority': '5', 'apns-topic': 'com.thespaghettidetective.ios', 'apns-collapse-id': f'collapse-{data["printerId"]}', }, ), token=device_token) if data['type'] != 'printProgress': message.apns.payload = APNSPayload(aps=Aps(sound="default")) return send(message, app=firebase_app) except (UnregisteredError, SenderIdMismatchError, firebase_admin.exceptions.InternalError): MobileDevice.objects.filter(device_token=device_token).update( deactivated_at=now()) except: import traceback traceback.print_exc() sentryClient.captureException()
def send_topic_message( message: messaging.Message, topic_name: str, app: "firebase_admin.App" = SETTINGS["DEFAULT_FIREBASE_APP"], **more_send_message_kwargs, ) -> Union[Optional[messaging.SendResponse], FirebaseError]: message.topic = topic_name try: return messaging.SendResponse( { "name": messaging.send( message, app=app, **more_send_message_kwargs) }, None, ) except FirebaseError as e: return e
def push(self, request): from fcm_django.models import FCMDevice from firebase_admin.messaging import Notification, Message, \ AndroidConfig, AndroidNotification, APNSPayload, Aps, APNSConfig for device in self.recipient.fcmdevice_set.all(): data = {} for data_attr in [ 'id', 'object_id', 'target_id', 'object_content_type', 'target_content_type' ]: value = getattr(self, data_attr) if value: data[data_attr] = '.'.join( value.natural_key()) if isinstance( value, ContentType) else str(value) # from objprint import op # op(data) result = device.send_message( Message( notification=Notification( title=self.push_config['title'], body=self.push_config['body'], # image=self.push_data['image_url']" ), data=data, android=AndroidConfig( collapse_key=self.push_config['android'] ['collapse_key'], priority=self.push_config['android']['priority'], notification=AndroidNotification( click_action=self.push_config['android'] ['click_action'], sound=self.push_config['android']['sound'])), apns=APNSConfig(payload=APNSPayload(aps=Aps( badge=self.recipient.unread_notifications.count(), category=self.push_config['apns']['category'], sound=self.push_config['apns']['sound'])))))
def send_to_device(msg, mobile_device): if not firebase_app: return kwargs = dict( data=msg, android=AndroidConfig(priority='high'), apns=APNSConfig( headers={'apns-push-type': 'background', 'apns-priority': '5'}, payload=APNSPayload( aps=Aps(content_available=True, category='post')) ), token=mobile_device.device_token ) try: message = Message(**kwargs) return send(message, app=firebase_app) except (UnregisteredError, SenderIdMismatchError, firebase_admin.exceptions.InternalError): MobileDevice.objects.filter(device_token=mobile_device.device_token).update(deactivated_at=now()) except Exception: import traceback; traceback.print_exc() capture_exception()
def _prepare_message(message: messaging.Message, token: str): message.token = token return copy(message)
def handle_send_topic_message(self, request, queryset): FCMDevice.send_topic_message( Message(notification=Notification( title="Test notification", body="Test single notification")), "test-topic", )