mirror of
https://github.com/zulip/zulip.git
synced 2025-11-20 14:38:46 +00:00
mentions: Send user group mention data to notification notices.
We will later use this data to include text like: `<sender> mentioned @<user_group>` instead of the current `<sender> mentioned you` when someone mentions a user group the current user is a part of in email/push notification. Part of #13080.
This commit is contained in:
committed by
Tim Abbott
parent
07d6ab9753
commit
167be7dbdc
@@ -110,7 +110,7 @@ from zerver.lib.message import (
|
||||
update_first_visible_message_id,
|
||||
wildcard_mention_allowed,
|
||||
)
|
||||
from zerver.lib.notification_data import UserMessageNotificationsData
|
||||
from zerver.lib.notification_data import UserMessageNotificationsData, get_user_group_mentions_data
|
||||
from zerver.lib.pysa import mark_sanitized
|
||||
from zerver.lib.queue import queue_json_publish
|
||||
from zerver.lib.realm_icon import realm_icon_url
|
||||
@@ -1792,7 +1792,14 @@ def build_message_send_dict(
|
||||
message.rendered_content_version = markdown_version
|
||||
links_for_embed = rendering_result.links_for_preview
|
||||
|
||||
# Add members of the mentioned user groups into `mentions_user_ids`.
|
||||
mentioned_user_groups_map = get_user_group_mentions_data(
|
||||
mentioned_user_ids=rendering_result.mentions_user_ids,
|
||||
mentioned_user_group_ids=list(rendering_result.mentions_user_group_ids),
|
||||
mention_data=mention_data,
|
||||
)
|
||||
|
||||
# For single user as well as user group mentions, we set the `mentioned`
|
||||
# flag on `UserMessage`
|
||||
for group_id in rendering_result.mentions_user_group_ids:
|
||||
members = mention_data.get_group_members(group_id)
|
||||
rendering_result.mentions_user_ids.update(members)
|
||||
@@ -1823,6 +1830,7 @@ def build_message_send_dict(
|
||||
sender_queue_id=sender_queue_id,
|
||||
realm=realm,
|
||||
mention_data=mention_data,
|
||||
mentioned_user_groups_map=mentioned_user_groups_map,
|
||||
message=message,
|
||||
rendering_result=rendering_result,
|
||||
active_user_ids=info["active_user_ids"],
|
||||
@@ -1960,7 +1968,14 @@ def do_send_messages(
|
||||
users: List[Dict[str, Union[int, List[str]]]] = []
|
||||
for user_id in user_list:
|
||||
flags = user_flags.get(user_id, [])
|
||||
users.append(dict(id=user_id, flags=flags))
|
||||
user_data = dict(id=user_id, flags=flags)
|
||||
|
||||
if user_id in send_request.mentioned_user_groups_map:
|
||||
user_data["mentioned_user_group_id"] = send_request.mentioned_user_groups_map[
|
||||
user_id
|
||||
]
|
||||
|
||||
users.append(user_data)
|
||||
|
||||
sender = send_request.message.sender
|
||||
message_type = wide_message_dict["type"]
|
||||
|
||||
@@ -96,6 +96,7 @@ class SendMessageRequest:
|
||||
sender_queue_id: Optional[str]
|
||||
realm: Realm
|
||||
mention_data: MentionData
|
||||
mentioned_user_groups_map: Dict[int, int]
|
||||
active_user_ids: Set[int]
|
||||
online_push_user_ids: Set[int]
|
||||
stream_push_user_ids: Set[int]
|
||||
|
||||
@@ -1355,6 +1355,7 @@ Output:
|
||||
acting_user_id=acting_user_id,
|
||||
private_message=kwargs.get("private_message", False),
|
||||
stream_name=kwargs.get("stream_name", None),
|
||||
mentioned_user_group_id=kwargs.get("mentioned_user_group_id", None),
|
||||
idle=kwargs.get("idle", True),
|
||||
already_notified=kwargs.get(
|
||||
"already_notified", {"email_notified": False, "push_notified": False}
|
||||
|
||||
@@ -8,6 +8,7 @@ from django.http import HttpRequest, HttpResponse
|
||||
from zerver.lib.actions import do_change_subscription_property, do_mute_topic
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import HostRequestMock, mock_queue_publish
|
||||
from zerver.lib.user_groups import create_user_group, remove_user_from_user_group
|
||||
from zerver.models import Recipient, Stream, Subscription, UserProfile, get_stream
|
||||
from zerver.tornado.event_queue import (
|
||||
ClientDescriptor,
|
||||
@@ -54,6 +55,30 @@ class MissedMessageNotificationsTest(ZulipTestCase):
|
||||
self.assertTrue(notified["email_notified"])
|
||||
self.assertTrue(notified["push_notified"])
|
||||
|
||||
with mock_queue_publish(
|
||||
"zerver.tornado.event_queue.queue_json_publish"
|
||||
) as mock_queue_json_publish:
|
||||
params = self.get_maybe_enqueue_notifications_parameters(
|
||||
message_id=1,
|
||||
acting_user_id=2,
|
||||
user_id=3,
|
||||
private_message=False,
|
||||
stream_name="Denmark",
|
||||
flags=["mentioned"],
|
||||
mentioned=True,
|
||||
mentioned_user_group_id=33,
|
||||
)
|
||||
notified = maybe_enqueue_notifications(**params)
|
||||
self.assertTrue(mock_queue_json_publish.call_count, 2)
|
||||
|
||||
push_notice = mock_queue_json_publish.call_args_list[0][0][1]
|
||||
self.assertEqual(push_notice["stream_name"], "Denmark")
|
||||
self.assertEqual(push_notice["mentioned_user_group_id"], 33)
|
||||
|
||||
email_notice = mock_queue_json_publish.call_args_list[1][0][1]
|
||||
self.assertEqual(email_notice["stream_name"], "Denmark")
|
||||
self.assertEqual(email_notice["mentioned_user_group_id"], 33)
|
||||
|
||||
def tornado_call(
|
||||
self,
|
||||
view_func: Callable[[HttpRequest, UserProfile], HttpResponse],
|
||||
@@ -106,6 +131,7 @@ class MissedMessageNotificationsTest(ZulipTestCase):
|
||||
"""Tests what arguments missedmessage_hook passes into maybe_enqueue_notifications.
|
||||
Combined with the previous test, this ensures that the missedmessage_hook is correct"""
|
||||
user_profile = self.example_user("hamlet")
|
||||
cordelia = self.example_user("cordelia")
|
||||
|
||||
user_profile.enable_online_push_notifications = False
|
||||
user_profile.save()
|
||||
@@ -318,6 +344,33 @@ class MissedMessageNotificationsTest(ZulipTestCase):
|
||||
user_profile.save()
|
||||
sub.save()
|
||||
|
||||
# Test with a user group mention
|
||||
hamlet_and_cordelia = create_user_group(
|
||||
"hamlet_and_cordelia", [user_profile, cordelia], cordelia.realm
|
||||
)
|
||||
client_descriptor = allocate_event_queue()
|
||||
self.assertTrue(client_descriptor.event_queue.empty())
|
||||
msg_id = self.send_stream_message(
|
||||
iago, "Denmark", content="@*hamlet_and_cordelia* what's up?"
|
||||
)
|
||||
with mock.patch("zerver.tornado.event_queue.maybe_enqueue_notifications") as mock_enqueue:
|
||||
missedmessage_hook(user_profile.id, client_descriptor, True)
|
||||
mock_enqueue.assert_called_once()
|
||||
args_dict = mock_enqueue.call_args_list[0][1]
|
||||
|
||||
assert_maybe_enqueue_notifications_call_args(
|
||||
args_dict=args_dict,
|
||||
message_id=msg_id,
|
||||
flags=["mentioned"],
|
||||
mentioned=True,
|
||||
stream_name="Denmark",
|
||||
mentioned_user_group_id=hamlet_and_cordelia.id,
|
||||
already_notified={"email_notified": True, "push_notified": True},
|
||||
)
|
||||
destroy_event_queue(client_descriptor.event_queue.id)
|
||||
remove_user_from_user_group(user_profile, hamlet_and_cordelia)
|
||||
remove_user_from_user_group(cordelia, hamlet_and_cordelia)
|
||||
|
||||
# Test the hook with a stream message with stream_push_notify
|
||||
change_subscription_properties(user_profile, stream, sub, {"push_notifications": True})
|
||||
client_descriptor = allocate_event_queue()
|
||||
|
||||
@@ -757,6 +757,7 @@ def missedmessage_hook(
|
||||
)
|
||||
|
||||
private_message = event["message"]["type"] == "private"
|
||||
mentioned_user_group_id = internal_data.get("mentioned_user_group_id")
|
||||
|
||||
stream_name = None
|
||||
if not private_message:
|
||||
@@ -777,6 +778,7 @@ def missedmessage_hook(
|
||||
message_id=message_id,
|
||||
private_message=private_message,
|
||||
stream_name=stream_name,
|
||||
mentioned_user_group_id=mentioned_user_group_id,
|
||||
idle=idle,
|
||||
already_notified=already_notified,
|
||||
)
|
||||
@@ -800,6 +802,7 @@ def maybe_enqueue_notifications(
|
||||
message_id: int,
|
||||
private_message: bool,
|
||||
stream_name: Optional[str],
|
||||
mentioned_user_group_id: Optional[int],
|
||||
idle: bool,
|
||||
already_notified: Dict[str, bool],
|
||||
) -> Dict[str, bool]:
|
||||
@@ -818,6 +821,7 @@ def maybe_enqueue_notifications(
|
||||
private_message, acting_user_id, idle
|
||||
)
|
||||
notice["stream_name"] = stream_name
|
||||
notice["mentioned_user_group_id"] = mentioned_user_group_id
|
||||
if not already_notified.get("push_notified"):
|
||||
queue_json_publish("missedmessage_mobile_notifications", notice)
|
||||
notified["push_notified"] = True
|
||||
@@ -832,6 +836,7 @@ def maybe_enqueue_notifications(
|
||||
private_message, acting_user_id, idle
|
||||
)
|
||||
notice["stream_name"] = stream_name
|
||||
notice["mentioned_user_group_id"] = mentioned_user_group_id
|
||||
if not already_notified.get("email_notified"):
|
||||
queue_json_publish("missedmessage_emails", notice, lambda notice: None)
|
||||
notified["email_notified"] = True
|
||||
@@ -933,6 +938,7 @@ def process_message_event(
|
||||
for user_data in users:
|
||||
user_profile_id: int = user_data["id"]
|
||||
flags: Collection[str] = user_data.get("flags", [])
|
||||
mentioned_user_group_id: Optional[int] = user_data.get("mentioned_user_group_id")
|
||||
|
||||
# If the recipient was offline and the message was a single or group PM to them
|
||||
# or they were @-notified potentially notify more immediately
|
||||
@@ -951,6 +957,7 @@ def process_message_event(
|
||||
# Remove fields sent through other pipes to save some space.
|
||||
internal_data.pop("flags")
|
||||
internal_data.pop("user_id")
|
||||
internal_data["mentioned_user_group_id"] = mentioned_user_group_id
|
||||
extra_user_data[user_profile_id] = dict(internal_data=internal_data)
|
||||
|
||||
# If the message isn't notifiable had the user been idle, then the user
|
||||
@@ -973,6 +980,7 @@ def process_message_event(
|
||||
message_id=message_id,
|
||||
private_message=private_message,
|
||||
stream_name=stream_name,
|
||||
mentioned_user_group_id=mentioned_user_group_id,
|
||||
idle=idle,
|
||||
already_notified={},
|
||||
)
|
||||
@@ -1196,12 +1204,18 @@ def maybe_enqueue_notifications_for_message_update(
|
||||
|
||||
idle = presence_idle or receiver_is_off_zulip(user_notifications_data.user_id)
|
||||
|
||||
# We don't yet support custom user group mentions for message edit notifications.
|
||||
# Users will still receive notifications (because of the mentioned flag), but those
|
||||
# will be as if they were mentioned personally.
|
||||
mentioned_user_group_id = None
|
||||
|
||||
maybe_enqueue_notifications(
|
||||
user_notifications_data=user_notifications_data,
|
||||
message_id=message_id,
|
||||
acting_user_id=acting_user_id,
|
||||
private_message=private_message,
|
||||
stream_name=stream_name,
|
||||
mentioned_user_group_id=mentioned_user_group_id,
|
||||
idle=idle,
|
||||
already_notified={},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user