diff --git a/zerver/lib/push_notifications.py b/zerver/lib/push_notifications.py index 159c55f22e..5ec89f1dc9 100644 --- a/zerver/lib/push_notifications.py +++ b/zerver/lib/push_notifications.py @@ -146,18 +146,22 @@ def _do_push_to_apns_service(user, message, apns_connection): frame = message.get_frame() apns_connection.gateway_server.send_notification_multiple(frame) +def send_apple_push_notification_to_user(user, alert, **extra_data): + # type: (UserProfile, Text, **Any) -> None + devices = PushDeviceToken.objects.filter(user=user, kind=PushDeviceToken.APNS) + send_apple_push_notification(user, devices, alert, **extra_data) + # Send a push notification to the desired clients # extra_data is a dict that will be passed to the # mobile app @statsd_increment("apple_push_notification") -def send_apple_push_notification(user, alert, **extra_data): - # type: (UserProfile, Text, **Any) -> None +def send_apple_push_notification(user, devices, alert, **extra_data): + # type: (UserProfile, List[PushDeviceToken], Text, **Any) -> None if not connection and not dbx_connection: logging.error("Attempting to send push notification, but no connection was found. " "This may be because we could not find the APNS Certificate file.") return - devices = PushDeviceToken.objects.filter(user=user, kind=PushDeviceToken.APNS) # Plain b64 token kept for debugging purposes tokens = [(b64_to_hex(device.token), device.ios_app_id, device.token) for device in devices] @@ -273,12 +277,13 @@ def handle_push_notification(user_profile_id, missed_message): return sender_str = message.sender.full_name - apple = num_push_devices_for_user(user_profile, kind=PushDeviceToken.APNS) android_devices = [device for device in PushDeviceToken.objects.filter(user=user_profile, kind=PushDeviceToken.GCM)] + apple_devices = list(PushDeviceToken.objects.filter(user=user_profile, + kind=PushDeviceToken.APNS)) - if apple or android_devices: + if apple_devices or android_devices: # TODO: set badge count in a better way # Determine what alert string to display based on the missed messages if message.recipient.type == Recipient.HUDDLE: @@ -290,9 +295,10 @@ def handle_push_notification(user_profile_id, missed_message): else: alert = "New Zulip mentions and private messages from %s" % (sender_str,) - if apple: + if apple_devices: apple_extra_data = {'message_ids': [message.id]} - send_apple_push_notification(user_profile, alert, badge=1, zulip=apple_extra_data) + send_apple_push_notification(user_profile, apple_devices, alert, + badge=1, zulip=apple_extra_data) if android_devices: content = message.content diff --git a/zerver/models.py b/zerver/models.py index 44173e0cf6..d36b0d1e87 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -721,7 +721,7 @@ class PushDeviceToken(models.Model): # sent to us from each device: # - APNS token if kind == APNS # - GCM registration id if kind == GCM - token = models.CharField(max_length=4096, unique=True) # type: Text + token = models.CharField(max_length=4096, unique=True) # type: bytes last_updated = models.DateTimeField(auto_now=True) # type: datetime.datetime # The user who's device this is diff --git a/zerver/tests/test_push_notifications.py b/zerver/tests/test_push_notifications.py index cd06a21710..6d6e1a497b 100644 --- a/zerver/tests/test_push_notifications.py +++ b/zerver/tests/test_push_notifications.py @@ -179,7 +179,7 @@ class SendNotificationTest(PushNotificationTest): self.assertEqual(set(message.tokens), set(self.tokens)) mock_send.side_effect = test_send - apn.send_apple_push_notification(self.user_profile, "test alert") + apn.send_apple_push_notification_to_user(self.user_profile, "test alert") self.assertEqual(mock_send.call_count, 1) @mock.patch('apns.GatewayConnection.send_notification_multiple') @@ -200,7 +200,7 @@ class SendNotificationTest(PushNotificationTest): def test_connection_single_none(self, mock_push, mock_info, mock_warn): # type: (mock.MagicMock, mock.MagicMock, mock.MagicMock) -> None apn.connection = None - apn.send_apple_push_notification(self.user_profile, "test alert") + apn.send_apple_push_notification_to_user(self.user_profile, "test alert") @mock.patch('logging.error') @mock.patch('apns.GatewayConnection.send_notification_multiple') @@ -208,7 +208,7 @@ class SendNotificationTest(PushNotificationTest): # type: (mock.MagicMock, mock.MagicMock) -> None apn.connection = None apn.dbx_connection = None - apn.send_apple_push_notification(self.user_profile, "test alert") + apn.send_apple_push_notification_to_user(self.user_profile, "test alert") class APNsFeedbackTest(PushNotificationTest): @mock.patch('logging.info')