Example #1
0
    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)
Example #2
0
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)
Example #3
0
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()
Example #5
0
    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)
Example #7
0
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
Example #8
0
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()
Example #10
0
    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
Example #11
0
    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()
Example #13
0
 def _prepare_message(message: messaging.Message, token: str):
     message.token = token
     return copy(message)
Example #14
0
 def handle_send_topic_message(self, request, queryset):
     FCMDevice.send_topic_message(
         Message(notification=Notification(
             title="Test notification", body="Test single notification")),
         "test-topic",
     )