notification_trigger: Rename `private_message` to `direct_message`.

This commit renames the 'PRIVATE_MESSAGE' attribute of the
'NotificationTriggers' class to 'DIRECT_MESSAGE'.

Custom migration to update the existing value in the database.

It includes 'TODO/compatibility' code to support the old
notification trigger value 'private_message' in the
push notification queue during the Zulip server upgrades.

Earlier 'private_message' was one of the possible values for the
'trigger' property of the '[`POST /zulip-outgoing-webhook`]' response;
Update the docs to reflect the change in the above-mentioned trigger
value.
This commit is contained in:
Prakhar Pratyush 2023-08-04 23:24:41 +05:30 committed by Tim Abbott
parent 3675a44471
commit c4e4737cc6
16 changed files with 88 additions and 50 deletions

View File

@ -20,6 +20,11 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 8.0
**Feature level 201**
* [`POST /zulip-outgoing-webhook`]: Renamed the notification trigger
`private_message` to `direct_message`.
**Feature level 200**
* [`PATCH /streams/{stream_id}`](/api/update-stream): Added

View File

@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
# Changes should be accompanied by documentation explaining what the
# new level means in api_docs/changelog.md, as well as "**Changes**"
# entries in the endpoint's documentation in `zulip.yaml`.
API_FEATURE_LEVEL = 200
API_FEATURE_LEVEL = 201
# Bump the minor PROVISION_VERSION to indicate that folks should provision
# only when going from an old version of the code to a newer version. Bump

View File

@ -514,7 +514,7 @@ def get_service_bot_events(
trigger = "mention"
# Direct message triggers for personal and huddle messages
elif (not is_stream) and (user_profile_id in active_user_ids):
trigger = NotificationTriggers.PRIVATE_MESSAGE
trigger = NotificationTriggers.DIRECT_MESSAGE
else:
return

View File

@ -209,7 +209,7 @@ class UserMessageNotificationsData:
# `mention_push_notify` and `stream_push_notify` are True, we
# want to classify it as a mention, since that's more salient.
if self.pm_push_notify:
return NotificationTriggers.PRIVATE_MESSAGE
return NotificationTriggers.DIRECT_MESSAGE
elif self.mention_push_notify:
return NotificationTriggers.MENTION
elif self.topic_wildcard_mention_in_followed_topic_push_notify:
@ -241,7 +241,7 @@ class UserMessageNotificationsData:
# `mention_email_notify` and `stream_email_notify` are True, we
# want to classify it as a mention, since that's more salient.
if self.pm_email_notify:
return NotificationTriggers.PRIVATE_MESSAGE
return NotificationTriggers.DIRECT_MESSAGE
elif self.mention_email_notify:
return NotificationTriggers.MENTION
elif self.topic_wildcard_mention_in_followed_topic_email_notify:

View File

@ -660,12 +660,12 @@ def get_gcm_alert(
display_recipient = get_display_recipient(message.recipient)
if (
message.recipient.type == Recipient.HUDDLE
and trigger == NotificationTriggers.PRIVATE_MESSAGE
and trigger == NotificationTriggers.DIRECT_MESSAGE
):
return f"New direct group message from {sender_str}"
elif (
message.recipient.type == Recipient.PERSONAL
and trigger == NotificationTriggers.PRIVATE_MESSAGE
and trigger == NotificationTriggers.DIRECT_MESSAGE
):
return f"New direct message from {sender_str}"
elif message.is_stream_message() and trigger == NotificationTriggers.MENTION:
@ -1136,6 +1136,12 @@ def handle_push_notification(user_profile_id: int, missed_message: Dict[str, Any
if trigger == "followed_topic_wildcard_mentioned":
trigger = NotificationTriggers.STREAM_WILDCARD_MENTION_IN_FOLLOWED_TOPIC # nocoverage
# TODO/compatibility: Translation code for the rename of
# `private_message` to `direct_message`. Remove this when
# one can no longer directly upgrade from 7.x to main.
if trigger == "private_message":
trigger = NotificationTriggers.DIRECT_MESSAGE # nocoverage
mentioned_user_group_name = None
# mentioned_user_group_id will be None if the user is personally mentioned
# regardless whether they are a member of the mentioned user group in the

View File

@ -418,7 +418,7 @@ def soft_reactivate_if_personal_notification(
if not user_profile.long_term_idle:
return
private_message = NotificationTriggers.PRIVATE_MESSAGE in unique_triggers
direct_message = NotificationTriggers.DIRECT_MESSAGE in unique_triggers
personal_mention = (
NotificationTriggers.MENTION in unique_triggers and mentioned_user_group_name is None
)
@ -429,7 +429,7 @@ def soft_reactivate_if_personal_notification(
NotificationTriggers.TOPIC_WILDCARD_MENTION_IN_FOLLOWED_TOPIC,
]
)
if not private_message and not personal_mention and not topic_wildcard_mention:
if not direct_message and not personal_mention and not topic_wildcard_mention:
return
queue_soft_reactivation(user_profile.id)

View File

@ -24,7 +24,7 @@ class Migration(migrations.Migration):
"trigger",
models.TextField(
choices=[
("private_message", "Private message"),
("direct_message", "Direct message"),
("mentioned", "Mention"),
("topic_wildcard_mentioned", "Topic wildcard mention"),
("stream_wildcard_mentioned", "Stream wildcard mention"),

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.3 on 2023-08-04 14:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("zerver", "0464_remove_realmplayground_url_prefix"),
]
operations = [
migrations.RunSQL(
"""
UPDATE zerver_scheduledmessagenotificationemail
SET trigger = 'direct_message'
WHERE trigger = 'private_message';
""",
reverse_sql="""
UPDATE zerver_scheduledmessagenotificationemail
SET trigger = 'private_message'
WHERE trigger = 'direct_message';
""",
),
]

View File

@ -4276,8 +4276,8 @@ class MissedMessageEmailAddress(models.Model):
class NotificationTriggers:
# "private_message" is for 1:1 direct messages as well as huddles
PRIVATE_MESSAGE = "private_message"
# "direct_message" is for 1:1 direct messages as well as huddles
DIRECT_MESSAGE = "direct_message"
MENTION = "mentioned"
TOPIC_WILDCARD_MENTION = "topic_wildcard_mentioned"
STREAM_WILDCARD_MENTION = "stream_wildcard_mentioned"
@ -4300,7 +4300,7 @@ class ScheduledMessageNotificationEmail(models.Model):
message = models.ForeignKey(Message, on_delete=CASCADE)
EMAIL_NOTIFICATION_TRIGGER_CHOICES = [
(NotificationTriggers.PRIVATE_MESSAGE, "Private message"),
(NotificationTriggers.DIRECT_MESSAGE, "Direct message"),
(NotificationTriggers.MENTION, "Mention"),
(NotificationTriggers.TOPIC_WILDCARD_MENTION, "Topic wildcard mention"),
(NotificationTriggers.STREAM_WILDCARD_MENTION, "Stream wildcard mention"),

View File

@ -16838,7 +16838,10 @@ paths:
type: string
description: |
What aspect of the message triggered the outgoing webhook notification.
Possible values include `private_message` and `mention`.
Possible values include `direct_message` and `mention`.
**Changes**: In Zulip 8.0 (feature level 201), renamed the trigger
`private_message` to `direct_message`.
token:
type: string
description: |

View File

@ -61,7 +61,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
) as m:
handle_missedmessage_emails(
cordelia.id,
{message.id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)},
{message.id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)},
)
m.assert_not_called()
@ -71,7 +71,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
) as m:
handle_missedmessage_emails(
hamlet.id,
{message.id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)},
{message.id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)},
)
m.assert_called_once()
@ -88,7 +88,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
) as m:
handle_missedmessage_emails(
hamlet.id,
{message.id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)},
{message.id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)},
)
m.assert_not_called()
@ -625,7 +625,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
result = self.client_patch("/json/messages/" + str(msg_id), {"content": " "})
self.assert_json_success(result)
handle_missedmessage_emails(
hamlet.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)}
hamlet.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)}
)
self.assert_length(mail.outbox, 0)
@ -645,11 +645,11 @@ class TestMessageNotificationEmails(ZulipTestCase):
result = self.client_patch("/json/messages/" + str(msg_id), {"content": " "})
self.assert_json_success(result)
handle_missedmessage_emails(
hamlet.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)}
hamlet.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)}
)
self.assert_length(mail.outbox, 0)
handle_missedmessage_emails(
iago.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE)}
iago.id, {msg_id: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE)}
)
self.assert_length(mail.outbox, 0)
@ -1292,7 +1292,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
{
msg_id_1: MissedMessageData(trigger=NotificationTriggers.MENTION),
msg_id_2: MissedMessageData(trigger=NotificationTriggers.STREAM_EMAIL),
msg_id_3: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE),
msg_id_3: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE),
},
)
@ -1335,8 +1335,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
handle_missedmessage_emails(
hamlet.id,
{
msg_id_1: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE),
msg_id_2: MissedMessageData(trigger=NotificationTriggers.PRIVATE_MESSAGE),
msg_id_1: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE),
msg_id_2: MissedMessageData(trigger=NotificationTriggers.DIRECT_MESSAGE),
},
)
self.assert_length(mail.outbox, 2)
@ -1660,7 +1660,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
hamlet.id,
{
personal_message_id: MissedMessageData(
trigger=NotificationTriggers.PRIVATE_MESSAGE
trigger=NotificationTriggers.DIRECT_MESSAGE
)
},
)

View File

@ -27,7 +27,7 @@ class TestNotificationData(ZulipTestCase):
user_data = self.create_user_notifications_data_object(user_id=user_id, pm_push_notify=True)
self.assertEqual(
user_data.get_push_notification_trigger(acting_user_id=acting_user_id, idle=True),
NotificationTriggers.PRIVATE_MESSAGE,
NotificationTriggers.DIRECT_MESSAGE,
)
self.assertTrue(user_data.is_push_notifiable(acting_user_id=acting_user_id, idle=True))
@ -116,7 +116,7 @@ class TestNotificationData(ZulipTestCase):
)
self.assertEqual(
user_data.get_push_notification_trigger(acting_user_id=acting_user_id, idle=False),
NotificationTriggers.PRIVATE_MESSAGE,
NotificationTriggers.DIRECT_MESSAGE,
)
self.assertTrue(user_data.is_push_notifiable(acting_user_id=acting_user_id, idle=False))
@ -195,7 +195,7 @@ class TestNotificationData(ZulipTestCase):
)
self.assertEqual(
user_data.get_email_notification_trigger(acting_user_id=acting_user_id, idle=True),
NotificationTriggers.PRIVATE_MESSAGE,
NotificationTriggers.DIRECT_MESSAGE,
)
self.assertTrue(user_data.is_email_notifiable(acting_user_id=acting_user_id, idle=True))

View File

@ -181,7 +181,7 @@ class TestSlackOutgoingWebhookService(ZulipTestCase):
"user_profile_id": 24,
"service_name": "test-service",
"command": "test content",
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
"message": {
"sender_id": 3,
"sender_realm_str": "zulip",

View File

@ -1106,7 +1106,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
with mock.patch(
"zerver.lib.push_notifications.gcm_client"
@ -1168,7 +1168,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
with mock.patch(
"zerver.lib.push_notifications.gcm_client"
@ -1227,7 +1227,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"user_profile_id": self.user_profile.id,
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
assert settings.PUSH_NOTIFICATION_BOUNCER_URL is not None
URL = settings.PUSH_NOTIFICATION_BOUNCER_URL + "/api/v1/remotes/push/notify"
@ -1257,7 +1257,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
# If the message is unread, we should send push notifications.
@ -1297,7 +1297,7 @@ class HandlePushNotificationTest(PushNotificationTest):
)
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
# Now, delete the message the normal way
do_delete_messages(user_profile.realm, [message])
@ -1330,7 +1330,7 @@ class HandlePushNotificationTest(PushNotificationTest):
)
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
# Now delete the message forcefully, so it just doesn't exist.
message.delete()
@ -1366,7 +1366,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=True), mock.patch(
"zerver.lib.push_notifications.get_message_payload_apns", return_value={"apns": True}
@ -1416,7 +1416,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
with mock.patch(
"zerver.lib.push_notifications.get_message_payload_apns", return_value={"apns": True}
@ -1679,7 +1679,7 @@ class HandlePushNotificationTest(PushNotificationTest):
self.user_profile.id,
{
"message_id": personal_message_id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
},
)
@ -1789,7 +1789,7 @@ class HandlePushNotificationTest(PushNotificationTest):
missed_message = {
"message_id": message.id,
"trigger": NotificationTriggers.PRIVATE_MESSAGE,
"trigger": NotificationTriggers.DIRECT_MESSAGE,
}
handle_push_notification(user_profile.id, missed_message)
mock_push_notifications.assert_called_once()
@ -1962,7 +1962,7 @@ class TestGetAPNsPayload(PushNotificationTest):
)
message = Message.objects.get(id=message_id)
payload = get_message_payload_apns(
user_profile, message, NotificationTriggers.PRIVATE_MESSAGE
user_profile, message, NotificationTriggers.DIRECT_MESSAGE
)
expected = {
"alert": {
@ -1997,7 +1997,7 @@ class TestGetAPNsPayload(PushNotificationTest):
)
message = Message.objects.get(id=message_id)
payload = get_message_payload_apns(
user_profile, message, NotificationTriggers.PRIVATE_MESSAGE
user_profile, message, NotificationTriggers.DIRECT_MESSAGE
)
expected = {
"alert": {
@ -2271,7 +2271,7 @@ class TestGetAPNsPayload(PushNotificationTest):
)
message = Message.objects.get(id=message_id)
payload = get_message_payload_apns(
user_profile, message, NotificationTriggers.PRIVATE_MESSAGE
user_profile, message, NotificationTriggers.DIRECT_MESSAGE
)
expected = {
"alert": {
@ -2392,7 +2392,7 @@ class TestGetGCMPayload(PushNotificationTest):
"King Hamlet mentioned everyone in #Verona",
)
def test_get_message_payload_gcm_private_message(self) -> None:
def test_get_message_payload_gcm_direct_message(self) -> None:
message = self.get_message(
Recipient.PERSONAL,
type_id=self.personal_recipient_user.id,
@ -2400,7 +2400,7 @@ class TestGetGCMPayload(PushNotificationTest):
)
hamlet = self.example_user("hamlet")
payload, gcm_options = get_message_payload_gcm(
hamlet, message, NotificationTriggers.PRIVATE_MESSAGE
hamlet, message, NotificationTriggers.DIRECT_MESSAGE
)
self.assertDictEqual(
payload,

View File

@ -144,18 +144,18 @@ class WorkerTest(ZulipTestCase):
hamlet_event1 = dict(
user_profile_id=hamlet.id,
message_id=hamlet1_msg_id,
trigger=NotificationTriggers.PRIVATE_MESSAGE,
trigger=NotificationTriggers.DIRECT_MESSAGE,
)
hamlet_event2 = dict(
user_profile_id=hamlet.id,
message_id=hamlet2_msg_id,
trigger=NotificationTriggers.PRIVATE_MESSAGE,
trigger=NotificationTriggers.DIRECT_MESSAGE,
mentioned_user_group_id=4,
)
othello_event = dict(
user_profile_id=othello.id,
message_id=othello_msg_id,
trigger=NotificationTriggers.PRIVATE_MESSAGE,
trigger=NotificationTriggers.DIRECT_MESSAGE,
)
events = [hamlet_event1, hamlet_event2, othello_event]
@ -176,7 +176,7 @@ class WorkerTest(ZulipTestCase):
bonus_event_hamlet = dict(
user_profile_id=hamlet.id,
message_id=hamlet3_msg_id,
trigger=NotificationTriggers.PRIVATE_MESSAGE,
trigger=NotificationTriggers.DIRECT_MESSAGE,
)
def check_row(
@ -184,7 +184,7 @@ class WorkerTest(ZulipTestCase):
scheduled_timestamp: datetime.datetime,
mentioned_user_group_id: Optional[int],
) -> None:
self.assertEqual(row.trigger, NotificationTriggers.PRIVATE_MESSAGE)
self.assertEqual(row.trigger, NotificationTriggers.DIRECT_MESSAGE)
self.assertEqual(row.scheduled_timestamp, scheduled_timestamp)
self.assertEqual(row.mentioned_user_group_id, mentioned_user_group_id)

View File

@ -56,7 +56,7 @@ class TestServiceBotBasics(ZulipTestCase):
expected = dict(
outgoing_webhooks=[
dict(trigger=NotificationTriggers.PRIVATE_MESSAGE, user_profile_id=outgoing_bot.id),
dict(trigger=NotificationTriggers.DIRECT_MESSAGE, user_profile_id=outgoing_bot.id),
],
)
@ -533,7 +533,7 @@ class TestServiceBotEventTriggers(ZulipTestCase):
assert self.bot_profile.bot_type
self.assertEqual(queue_name, BOT_TYPE_TO_QUEUE_NAME[self.bot_profile.bot_type])
self.assertEqual(trigger_event["user_profile_id"], self.bot_profile.id)
self.assertEqual(trigger_event["trigger"], NotificationTriggers.PRIVATE_MESSAGE)
self.assertEqual(trigger_event["trigger"], NotificationTriggers.DIRECT_MESSAGE)
self.assertEqual(trigger_event["message"]["sender_email"], sender.email)
display_recipients = [
trigger_event["message"]["display_recipient"][0]["email"],
@ -576,7 +576,7 @@ class TestServiceBotEventTriggers(ZulipTestCase):
self.assertEqual(queue_name, BOT_TYPE_TO_QUEUE_NAME[self.bot_profile.bot_type])
self.assertIn(trigger_event["user_profile_id"], profile_ids)
profile_ids.remove(trigger_event["user_profile_id"])
self.assertEqual(trigger_event["trigger"], NotificationTriggers.PRIVATE_MESSAGE)
self.assertEqual(trigger_event["trigger"], NotificationTriggers.DIRECT_MESSAGE)
self.assertEqual(trigger_event["message"]["sender_email"], sender.email)
self.assertEqual(trigger_event["message"]["type"], "private")