Send push notifications more aggresively

Unbundle the push notifications from the missed message queue processors
and handlers. This makes notifications more immediate, and sets things up
for better badge count handling, and possibly per-stream filtering.

(imported from commit 11840301751b0bbcb3a99848ff9868d9023b665b)
This commit is contained in:
acrefoot
2013-11-18 18:55:24 -05:00
parent bbda1d93c4
commit 8ee7536012
3 changed files with 28 additions and 15 deletions

View File

@@ -1994,25 +1994,32 @@ def do_send_missedmessage_events(user_profile, missed_messages):
user_profile.last_reminder = datetime.datetime.now()
user_profile.save(update_fields=['last_reminder'])
if user_profile.enable_offline_push_notifications:
if num_push_devices_for_user(user_profile) == 0:
return
badge_count = len(missed_messages)
@statsd_increment("push_notifications")
def handle_push_notification(user_profile_id, missed_message):
user_profile = get_user_profile_by_id(user_profile_id)
message = UserMessage.objects.get(user_profile=user_profile,
message__id=missed_message['message_id'],
flags=~UserMessage.flags.read).message
sender_str = message.sender.full_name
if user_profile.enable_offline_push_notifications and num_push_devices_for_user(user_profile):
#TODO: set badge count in a better way
# Determine what alert string to display based on the missed messages
if all(msg.recipient.type == Recipient.HUDDLE for msg in missed_messages):
alert = "New private group message%s from %s" % (plural_messages, sender_str)
elif all(msg.recipient.type == Recipient.PERSONAL for msg in missed_messages):
alert = "New private message%s from %s" % (plural_messages, sender_str)
elif all(msg.recipient.type == Recipient.STREAM for msg in missed_messages):
alert = "New mention%s from %s" % (plural_messages, sender_str)
if message.recipient.type == Recipient.HUDDLE:
alert = "New private group message from %s" % (sender_str,)
elif message.recipient.type == Recipient.PERSONAL:
alert = "New private message from %s" % (sender_str,)
elif message.recipient.type == Recipient.STREAM:
alert = "New mention from %s" % (sender_str,)
else:
alert = "New Zulip mentions and private messages from %s" % (sender_str,)
extra_data = {'message_ids': [message.id]}
extra_data = {'message_ids': [amsg.id for amsg in missed_messages]}
send_apple_push_notification(user_profile, alert, badge=badge_count, zulip=extra_data)
logging.info("sending push notification %r, %r" % (user_profile, alert))
send_apple_push_notification(user_profile, alert, badge=1, zulip=extra_data)
return
def handle_missedmessage_emails(user_profile_id, missed_email_events):
message_ids = [event.get('message_id') for event in missed_email_events]

View File

@@ -69,6 +69,7 @@ def missedmessage_hook(user_profile_id, queue, last_for_client):
for msg_id in message_ids:
event = build_offline_notification_event(user_profile_id, msg_id)
queue_json_publish("missedmessage_emails", event, lambda event: None)
queue_json_publish("missedmessage_mobile_notifications", event, lambda event: None)
def cache_load_message_data(message_id, users):
# Get everything that we'll need out of memcached in one fetch, to save round-trip times:
@@ -169,7 +170,6 @@ def process_new_message(data):
received_pm = message.recipient.type in (Recipient.PERSONAL, Recipient.HUDDLE) and \
user_profile_id != message.sender.id
mentioned = 'mentioned' in flags
if (received_pm or mentioned) and receiver_is_idle(user_profile, realm_presences):
if receives_offline_notifications(user_profile):
event = build_offline_notification_event(user_profile_id, message.id)
@@ -177,6 +177,7 @@ def process_new_message(data):
# We require RabbitMQ to do this, as we can't call the email handler
# from the Tornado process. So if there's no rabbitmq support do nothing
queue_json_publish("missedmessage_emails", event, lambda event: None)
queue_json_publish("missedmessage_mobile_notifications", event, lambda event: None)
for client, flags in send_to_clients.itervalues():
if not client.accepts_event_type('message'):

View File

@@ -13,7 +13,7 @@ from zerver.lib.actions import handle_missedmessage_emails, do_send_confirmation
do_update_user_activity, do_update_user_activity_interval, do_update_user_presence, \
internal_send_message, send_local_email_template_with_delay, clear_followup_emails_queue, \
check_send_message, extract_recipients, one_click_unsubscribe_link, \
enqueue_welcome_emails
enqueue_welcome_emails, handle_push_notification
from zerver.lib.digest import handle_digest_email
from zerver.decorator import JsonableError
from zerver.lib.socket import req_redis_key
@@ -179,6 +179,11 @@ class MissedMessageWorker(QueueProcessingWorker):
# of messages
time.sleep(2 * 60)
@assign_queue('missedmessage_mobile_notifications')
class PushNotificationsWorker(QueueProcessingWorker):
def consume(self, data):
handle_push_notification(data['user_profile_id'], data)
def make_feedback_client():
sys.path.append(os.path.join(os.path.dirname(__file__), '../../api'))
import zulip