mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
push notif: Send a batch of message IDs in one remove payload.
When a bunch of messages with active notifications are all read at once -- e.g. by the user choosing to mark all messages, or all in a stream, as read, or just scrolling quickly through a PM conversation -- there can be a large batch of this information to convey. Doing it in a single GCM/FCM message is better for server congestion, and for the device's battery. The corresponding client-side logic is in zulip/zulip-mobile#3343 . Existing clients today only understand one message ID at a time; so accommodate them by sending individual GCM/FCM messages up to an arbitrary threshold, with the rest only as a batch. Also add an explicit test for this logic. The existing tests that happen to cause this function to run don't exercise the last condition, so without a new test `--coverage` complains.
This commit is contained in:
@@ -605,18 +605,21 @@ def get_message_payload_gcm(
|
||||
return data, gcm_options
|
||||
|
||||
def get_remove_payload_gcm(
|
||||
user_profile: UserProfile, message_id: int,
|
||||
user_profile: UserProfile, message_ids: List[int],
|
||||
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
||||
'''A `remove` payload + options, for Android via GCM/FCM.'''
|
||||
gcm_payload = get_base_payload(user_profile.realm)
|
||||
gcm_payload.update({
|
||||
'event': 'remove',
|
||||
'zulip_message_id': message_id, # message_id is reserved for CCS
|
||||
'zulip_message_ids': ','.join(str(id) for id in message_ids),
|
||||
# Older clients (all clients older than 2019-02-13) look only at
|
||||
# `zulip_message_id` and ignore `zulip_message_ids`. Do our best.
|
||||
'zulip_message_id': message_ids[0],
|
||||
})
|
||||
gcm_options = {'priority': 'normal'}
|
||||
return gcm_payload, gcm_options
|
||||
|
||||
def handle_remove_push_notification(user_profile_id: int, message_id: int) -> None:
|
||||
def handle_remove_push_notification(user_profile_id: int, message_ids: List[int]) -> None:
|
||||
"""This should be called when a message that had previously had a
|
||||
mobile push executed is read. This triggers a mobile push notifica
|
||||
mobile app when the message is read on the server, to remove the
|
||||
@@ -624,8 +627,9 @@ def handle_remove_push_notification(user_profile_id: int, message_id: int) -> No
|
||||
|
||||
"""
|
||||
user_profile = get_user_profile_by_id(user_profile_id)
|
||||
message, user_message = access_message(user_profile, message_id)
|
||||
gcm_payload, gcm_options = get_remove_payload_gcm(user_profile, message_id)
|
||||
user_messages = [access_message(user_profile, message_id)[1]
|
||||
for message_id in message_ids]
|
||||
gcm_payload, gcm_options = get_remove_payload_gcm(user_profile, message_ids)
|
||||
|
||||
if uses_notification_bouncer():
|
||||
try:
|
||||
@@ -644,8 +648,10 @@ def handle_remove_push_notification(user_profile_id: int, message_id: int) -> No
|
||||
if android_devices:
|
||||
send_android_push_notification(android_devices, gcm_payload, gcm_options)
|
||||
|
||||
user_message.flags.active_mobile_push_notification = False
|
||||
user_message.save(update_fields=["flags"])
|
||||
for user_message in user_messages:
|
||||
# TODO make this O(1) queries... including access_message, above
|
||||
user_message.flags.active_mobile_push_notification = False
|
||||
user_message.save(update_fields=["flags"])
|
||||
|
||||
@statsd_increment("push_notifications")
|
||||
def handle_push_notification(user_profile_id: int, missed_message: Dict[str, Any]) -> None:
|
||||
|
||||
Reference in New Issue
Block a user