2022-04-18 22:46:07 +02:00
|
|
|
import math
|
2021-06-11 14:37:25 +02:00
|
|
|
from dataclasses import dataclass
|
2022-04-18 22:46:07 +02:00
|
|
|
from typing import Any, Collection, Dict, List, Optional, Set
|
2021-07-01 13:55:39 +02:00
|
|
|
|
|
|
|
from zerver.lib.mention import MentionData
|
2022-04-18 22:46:07 +02:00
|
|
|
from zerver.lib.user_groups import get_user_group_direct_member_ids
|
2023-02-03 22:33:37 +01:00
|
|
|
from zerver.models import NotificationTriggers, UserGroup, UserProfile, UserTopic
|
2021-06-11 14:37:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class UserMessageNotificationsData:
|
2021-06-23 10:44:34 +02:00
|
|
|
user_id: int
|
2021-06-11 14:37:25 +02:00
|
|
|
online_push_enabled: bool
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
pm_email_notify: bool
|
|
|
|
pm_push_notify: bool
|
|
|
|
mention_email_notify: bool
|
|
|
|
mention_push_notify: bool
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_email_notify: bool
|
|
|
|
stream_wildcard_mention_push_notify: bool
|
2021-06-11 14:37:25 +02:00
|
|
|
stream_push_notify: bool
|
|
|
|
stream_email_notify: bool
|
2023-05-28 17:03:04 +02:00
|
|
|
followed_topic_push_notify: bool
|
2023-05-17 16:01:16 +02:00
|
|
|
followed_topic_email_notify: bool
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_push_notify: bool
|
|
|
|
stream_wildcard_mention_in_followed_topic_email_notify: bool
|
2021-06-11 14:37:25 +02:00
|
|
|
sender_is_muted: bool
|
2022-10-22 13:25:06 +02:00
|
|
|
disable_external_notifications: bool
|
2021-06-11 14:37:25 +02:00
|
|
|
|
|
|
|
def __post_init__(self) -> None:
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
# Check that there's no dubious data.
|
|
|
|
if self.pm_email_notify or self.pm_push_notify:
|
2023-05-17 16:01:16 +02:00
|
|
|
assert not (
|
|
|
|
self.stream_email_notify
|
|
|
|
or self.stream_push_notify
|
|
|
|
or self.followed_topic_email_notify
|
2023-05-28 17:03:04 +02:00
|
|
|
or self.followed_topic_push_notify
|
2023-05-17 16:01:16 +02:00
|
|
|
)
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
|
2023-05-28 17:03:04 +02:00
|
|
|
if (
|
|
|
|
self.stream_email_notify
|
|
|
|
or self.stream_push_notify
|
|
|
|
or self.followed_topic_email_notify
|
|
|
|
or self.followed_topic_push_notify
|
|
|
|
):
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
assert not (self.pm_email_notify or self.pm_push_notify)
|
2021-06-15 14:30:51 +02:00
|
|
|
|
2021-06-18 14:16:16 +02:00
|
|
|
@classmethod
|
|
|
|
def from_user_id_sets(
|
|
|
|
cls,
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
*,
|
2021-06-18 14:16:16 +02:00
|
|
|
user_id: int,
|
|
|
|
flags: Collection[str],
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
private_message: bool,
|
2022-10-22 13:25:06 +02:00
|
|
|
disable_external_notifications: bool,
|
2021-06-18 14:16:16 +02:00
|
|
|
online_push_user_ids: Set[int],
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
pm_mention_push_disabled_user_ids: Set[int],
|
|
|
|
pm_mention_email_disabled_user_ids: Set[int],
|
2021-06-18 14:16:16 +02:00
|
|
|
stream_push_user_ids: Set[int],
|
|
|
|
stream_email_user_ids: Set[int],
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_user_ids: Set[int],
|
2023-05-28 17:03:04 +02:00
|
|
|
followed_topic_push_user_ids: Set[int],
|
2023-05-17 16:01:16 +02:00
|
|
|
followed_topic_email_user_ids: Set[int],
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_user_ids: Set[int],
|
2021-06-18 14:16:16 +02:00
|
|
|
muted_sender_user_ids: Set[int],
|
2021-12-19 12:04:36 +01:00
|
|
|
all_bot_user_ids: Set[int],
|
2021-06-18 14:16:16 +02:00
|
|
|
) -> "UserMessageNotificationsData":
|
2021-12-19 12:04:36 +01:00
|
|
|
if user_id in all_bot_user_ids:
|
|
|
|
# Don't send any notifications to bots
|
|
|
|
return cls(
|
|
|
|
user_id=user_id,
|
|
|
|
pm_email_notify=False,
|
|
|
|
mention_email_notify=False,
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_email_notify=False,
|
2021-12-19 12:04:36 +01:00
|
|
|
pm_push_notify=False,
|
|
|
|
mention_push_notify=False,
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_push_notify=False,
|
2021-12-19 12:04:36 +01:00
|
|
|
online_push_enabled=False,
|
|
|
|
stream_push_notify=False,
|
|
|
|
stream_email_notify=False,
|
2023-05-28 17:03:04 +02:00
|
|
|
followed_topic_push_notify=False,
|
2023-05-17 16:01:16 +02:00
|
|
|
followed_topic_email_notify=False,
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_push_notify=False,
|
|
|
|
stream_wildcard_mention_in_followed_topic_email_notify=False,
|
2021-12-19 12:04:36 +01:00
|
|
|
sender_is_muted=False,
|
2022-10-22 13:25:06 +02:00
|
|
|
disable_external_notifications=False,
|
2021-12-19 12:04:36 +01:00
|
|
|
)
|
|
|
|
|
2023-06-03 16:51:38 +02:00
|
|
|
# `stream_wildcard_mention_user_ids` are those user IDs for whom stream wildcard
|
|
|
|
# mentions should obey notification settings of personal mentions. Hence, it isn't an
|
|
|
|
# independent notification setting and acts as a wrapper.
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
pm_email_notify = user_id not in pm_mention_email_disabled_user_ids and private_message
|
|
|
|
mention_email_notify = (
|
|
|
|
user_id not in pm_mention_email_disabled_user_ids and "mentioned" in flags
|
|
|
|
)
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_email_notify = (
|
|
|
|
user_id in stream_wildcard_mention_user_ids
|
2021-08-10 15:41:41 +02:00
|
|
|
and user_id not in pm_mention_email_disabled_user_ids
|
|
|
|
and "wildcard_mentioned" in flags
|
|
|
|
)
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_email_notify = (
|
|
|
|
user_id in stream_wildcard_mention_in_followed_topic_user_ids
|
2023-06-02 09:42:58 +02:00
|
|
|
and user_id not in pm_mention_email_disabled_user_ids
|
|
|
|
and "wildcard_mentioned" in flags
|
|
|
|
)
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
|
|
|
|
pm_push_notify = user_id not in pm_mention_push_disabled_user_ids and private_message
|
|
|
|
mention_push_notify = (
|
|
|
|
user_id not in pm_mention_push_disabled_user_ids and "mentioned" in flags
|
|
|
|
)
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_push_notify = (
|
|
|
|
user_id in stream_wildcard_mention_user_ids
|
2021-08-10 15:41:41 +02:00
|
|
|
and user_id not in pm_mention_push_disabled_user_ids
|
|
|
|
and "wildcard_mentioned" in flags
|
|
|
|
)
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_push_notify = (
|
|
|
|
user_id in stream_wildcard_mention_in_followed_topic_user_ids
|
2023-06-02 09:42:58 +02:00
|
|
|
and user_id not in pm_mention_push_disabled_user_ids
|
|
|
|
and "wildcard_mentioned" in flags
|
|
|
|
)
|
2021-06-18 14:16:16 +02:00
|
|
|
return cls(
|
2021-06-23 10:44:34 +02:00
|
|
|
user_id=user_id,
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
pm_email_notify=pm_email_notify,
|
|
|
|
mention_email_notify=mention_email_notify,
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_email_notify=stream_wildcard_mention_email_notify,
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
pm_push_notify=pm_push_notify,
|
|
|
|
mention_push_notify=mention_push_notify,
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_push_notify=stream_wildcard_mention_push_notify,
|
2021-06-18 14:16:16 +02:00
|
|
|
online_push_enabled=(user_id in online_push_user_ids),
|
|
|
|
stream_push_notify=(user_id in stream_push_user_ids),
|
|
|
|
stream_email_notify=(user_id in stream_email_user_ids),
|
2023-05-28 17:03:04 +02:00
|
|
|
followed_topic_push_notify=(user_id in followed_topic_push_user_ids),
|
2023-05-17 16:01:16 +02:00
|
|
|
followed_topic_email_notify=(user_id in followed_topic_email_user_ids),
|
2023-06-03 16:51:38 +02:00
|
|
|
stream_wildcard_mention_in_followed_topic_push_notify=stream_wildcard_mention_in_followed_topic_push_notify,
|
|
|
|
stream_wildcard_mention_in_followed_topic_email_notify=stream_wildcard_mention_in_followed_topic_email_notify,
|
2021-06-18 14:16:16 +02:00
|
|
|
sender_is_muted=(user_id in muted_sender_user_ids),
|
2022-10-22 13:25:06 +02:00
|
|
|
disable_external_notifications=disable_external_notifications,
|
2021-06-18 14:16:16 +02:00
|
|
|
)
|
|
|
|
|
2021-06-25 13:58:53 +02:00
|
|
|
# For these functions, acting_user_id is the user sent a message
|
|
|
|
# (or edited a message) triggering the event for which we need to
|
|
|
|
# determine notifiability.
|
2022-10-13 11:48:33 +02:00
|
|
|
def trivially_should_not_notify(self, acting_user_id: int) -> bool:
|
|
|
|
"""Common check for reasons not to trigger a notification that arex
|
|
|
|
independent of users' notification settings and thus don't
|
|
|
|
depend on what type of notification (email/push) it is.
|
|
|
|
"""
|
|
|
|
if self.user_id == acting_user_id:
|
|
|
|
return True
|
|
|
|
|
|
|
|
if self.sender_is_muted:
|
|
|
|
return True
|
|
|
|
|
2022-10-22 13:25:06 +02:00
|
|
|
if self.disable_external_notifications:
|
|
|
|
return True
|
|
|
|
|
2022-10-13 11:48:33 +02:00
|
|
|
return False
|
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
def is_notifiable(self, acting_user_id: int, idle: bool) -> bool:
|
|
|
|
return self.is_email_notifiable(acting_user_id, idle) or self.is_push_notifiable(
|
|
|
|
acting_user_id, idle
|
|
|
|
)
|
2021-06-15 14:30:51 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
def is_push_notifiable(self, acting_user_id: int, idle: bool) -> bool:
|
|
|
|
return self.get_push_notification_trigger(acting_user_id, idle) is not None
|
2021-06-24 15:44:42 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
def get_push_notification_trigger(self, acting_user_id: int, idle: bool) -> Optional[str]:
|
2021-06-15 14:30:51 +02:00
|
|
|
if not idle and not self.online_push_enabled:
|
2021-06-24 15:44:42 +02:00
|
|
|
return None
|
2021-06-15 14:30:51 +02:00
|
|
|
|
2022-10-13 11:48:33 +02:00
|
|
|
if self.trivially_should_not_notify(acting_user_id):
|
2021-06-24 15:44:42 +02:00
|
|
|
return None
|
2021-06-15 14:30:51 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
# The order here is important. If, for example, both
|
|
|
|
# `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:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.PRIVATE_MESSAGE
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
elif self.mention_push_notify:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.MENTION
|
2023-06-03 16:51:38 +02:00
|
|
|
elif self.stream_wildcard_mention_in_followed_topic_push_notify:
|
|
|
|
return NotificationTriggers.STREAM_WILDCARD_MENTION_IN_FOLLOWED_TOPIC
|
|
|
|
elif self.stream_wildcard_mention_push_notify:
|
|
|
|
return NotificationTriggers.STREAM_WILDCARD_MENTION
|
2023-05-28 17:03:04 +02:00
|
|
|
elif self.followed_topic_push_notify:
|
|
|
|
return NotificationTriggers.FOLLOWED_TOPIC_PUSH
|
2021-06-24 15:44:42 +02:00
|
|
|
elif self.stream_push_notify:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.STREAM_PUSH
|
2021-06-24 15:44:42 +02:00
|
|
|
else:
|
|
|
|
return None
|
2021-06-15 14:30:51 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
def is_email_notifiable(self, acting_user_id: int, idle: bool) -> bool:
|
|
|
|
return self.get_email_notification_trigger(acting_user_id, idle) is not None
|
2021-06-24 15:44:42 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
def get_email_notification_trigger(self, acting_user_id: int, idle: bool) -> Optional[str]:
|
2021-06-15 14:30:51 +02:00
|
|
|
if not idle:
|
2021-06-24 15:44:42 +02:00
|
|
|
return None
|
2021-06-15 14:30:51 +02:00
|
|
|
|
2022-10-13 11:48:33 +02:00
|
|
|
if self.trivially_should_not_notify(acting_user_id):
|
2021-06-24 15:44:42 +02:00
|
|
|
return None
|
2021-06-15 14:30:51 +02:00
|
|
|
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
# The order here is important. If, for example, both
|
|
|
|
# `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:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.PRIVATE_MESSAGE
|
notifications: Calculate PMs/mentions settings like other settings.
Previously, we checked for the `enable_offline_email_notifications` and
`enable_offline_push_notifications` settings (which determine whether the
user will receive notifications for PMs and mentions) just before sending
notifications. This has a few problem:
1. We do not have access to all the user settings in the notification
handlers (`handle_missedmessage_emails` and `handle_push_notifications`),
and therefore, we cannot correctly determine whether the notification should
be sent. Checks like the following which existed previously, will, for
example, incorrectly not send notifications even when stream email
notifications are enabled-
```
if not receives_offline_email_notifications(user_profile):
return
```
With this commit, we simply do not enqueue notifications if the "offline"
settings are disabled, which fixes that bug.
Additionally, this also fixes a bug with the "online push notifications"
feature, which was, if someone were to:
* turn off notifications for PMs and mentions (`enable_offline_push_notifications`)
* turn on stream push notifications (`enable_stream_push_notifications`)
* turn on "online push" (`enable_online_push_notifications`)
then, they would still receive notifications for PMs when online.
This isn't how the "online push enabled" feature is supposed to work;
it should only act as a wrapper around the other notification settings.
The buggy code was this in `handle_push_notifications`:
```
if not (
receives_offline_push_notifications(user_profile)
or receives_online_push_notifications(user_profile)
):
return
// send notifications
```
This commit removes that code, and extends our `notification_data.py` logic
to cover this case, along with tests.
2. The name for these settings is slightly misleading. They essentially
talk about "what to send notifications for" (PMs and mentions), and not
"when to send notifications" (offline). This commit improves this condition
by restricting the use of this term only to the database field, and using
clearer names everywhere else. This distinction will be important to have
non-confusing code when we implement multiple options for notifications
in the future as dropdown (never/when offline/when offline or online, etc).
3. We should ideally re-check all notification settings just before the
notifications are sent. This is especially important for email notifications,
which may be sent after a long time after the message was sent. We will
in the future add code to thoroughly re-check settings before sending
notifications in a clean manner, but temporarily not re-checking isn't
a terrible scenario either.
2021-07-14 15:34:01 +02:00
|
|
|
elif self.mention_email_notify:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.MENTION
|
2023-06-03 16:51:38 +02:00
|
|
|
elif self.stream_wildcard_mention_in_followed_topic_email_notify:
|
|
|
|
return NotificationTriggers.STREAM_WILDCARD_MENTION_IN_FOLLOWED_TOPIC
|
|
|
|
elif self.stream_wildcard_mention_email_notify:
|
|
|
|
return NotificationTriggers.STREAM_WILDCARD_MENTION
|
2023-05-17 16:01:16 +02:00
|
|
|
elif self.followed_topic_email_notify:
|
|
|
|
return NotificationTriggers.FOLLOWED_TOPIC_EMAIL
|
2021-06-24 15:44:42 +02:00
|
|
|
elif self.stream_email_notify:
|
2021-07-09 13:38:12 +02:00
|
|
|
return NotificationTriggers.STREAM_EMAIL
|
2021-06-24 15:44:42 +02:00
|
|
|
else:
|
|
|
|
return None
|
2021-07-01 13:55:39 +02:00
|
|
|
|
|
|
|
|
2023-01-21 11:11:36 +01:00
|
|
|
def user_allows_notifications_in_StreamTopic(
|
|
|
|
stream_is_muted: bool,
|
2023-02-03 22:33:37 +01:00
|
|
|
visibility_policy: int,
|
2023-01-21 11:11:36 +01:00
|
|
|
stream_specific_setting: Optional[bool],
|
|
|
|
global_setting: bool,
|
|
|
|
) -> bool:
|
|
|
|
"""
|
2023-02-03 22:33:37 +01:00
|
|
|
Captures the hierarchy of notification settings, where visibility policy is considered first,
|
|
|
|
followed by stream-specific settings, and the global-setting in the UserProfile is the fallback.
|
2023-01-21 11:11:36 +01:00
|
|
|
"""
|
2023-03-12 16:19:42 +01:00
|
|
|
if stream_is_muted and visibility_policy != UserTopic.VisibilityPolicy.UNMUTED:
|
2023-02-03 22:33:37 +01:00
|
|
|
return False
|
|
|
|
|
2023-03-12 16:19:42 +01:00
|
|
|
if visibility_policy == UserTopic.VisibilityPolicy.MUTED:
|
2023-01-21 11:11:36 +01:00
|
|
|
return False
|
|
|
|
|
|
|
|
if stream_specific_setting is not None:
|
|
|
|
return stream_specific_setting
|
|
|
|
|
|
|
|
return global_setting
|
|
|
|
|
|
|
|
|
2021-07-01 13:55:39 +02:00
|
|
|
def get_user_group_mentions_data(
|
|
|
|
mentioned_user_ids: Set[int], mentioned_user_group_ids: List[int], mention_data: MentionData
|
|
|
|
) -> Dict[int, int]:
|
|
|
|
# Maps user_id -> mentioned user_group_id
|
|
|
|
mentioned_user_groups_map: Dict[int, int] = dict()
|
|
|
|
|
|
|
|
# Add members of the mentioned user groups into `mentions_user_ids`.
|
|
|
|
for group_id in mentioned_user_group_ids:
|
|
|
|
member_ids = mention_data.get_group_members(group_id)
|
|
|
|
for member_id in member_ids:
|
|
|
|
if member_id in mentioned_user_ids:
|
|
|
|
# If a user is also mentioned personally, we use that as a trigger
|
|
|
|
# for notifications.
|
|
|
|
continue
|
|
|
|
|
|
|
|
if member_id in mentioned_user_groups_map:
|
|
|
|
# If multiple user groups are mentioned, we prefer the
|
|
|
|
# user group with the least members for email/mobile
|
|
|
|
# notifications.
|
|
|
|
previous_group_id = mentioned_user_groups_map[member_id]
|
|
|
|
previous_group_member_ids = mention_data.get_group_members(previous_group_id)
|
|
|
|
|
|
|
|
if len(previous_group_member_ids) > len(member_ids):
|
|
|
|
mentioned_user_groups_map[member_id] = group_id
|
|
|
|
else:
|
|
|
|
mentioned_user_groups_map[member_id] = group_id
|
|
|
|
|
|
|
|
return mentioned_user_groups_map
|
2022-04-18 22:46:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_mentioned_user_group_name(
|
|
|
|
messages: List[Dict[str, Any]], user_profile: UserProfile
|
|
|
|
) -> Optional[str]:
|
|
|
|
"""Returns the user group name to display in the email notification
|
|
|
|
if user group(s) are mentioned.
|
|
|
|
|
|
|
|
This implements the same algorithm as get_user_group_mentions_data
|
|
|
|
in zerver/lib/notification_data.py, but we're passed a list of
|
|
|
|
messages instead.
|
|
|
|
"""
|
|
|
|
for message in messages:
|
|
|
|
if message["mentioned_user_group_id"] is None and message["trigger"] == "mentioned":
|
|
|
|
# The user has also been personally mentioned, so that gets prioritized.
|
|
|
|
return None
|
|
|
|
|
|
|
|
# These IDs are those of the smallest user groups mentioned in each message.
|
|
|
|
mentioned_user_group_ids = [
|
|
|
|
message["mentioned_user_group_id"]
|
|
|
|
for message in messages
|
|
|
|
if message["mentioned_user_group_id"] is not None
|
|
|
|
]
|
|
|
|
|
|
|
|
# We now want to calculate the name of the smallest user group mentioned among
|
|
|
|
# all these messages.
|
|
|
|
smallest_user_group_size = math.inf
|
|
|
|
smallest_user_group_name = None
|
|
|
|
for user_group_id in mentioned_user_group_ids:
|
|
|
|
current_user_group = UserGroup.objects.get(id=user_group_id, realm=user_profile.realm)
|
|
|
|
current_user_group_size = len(get_user_group_direct_member_ids(current_user_group))
|
|
|
|
|
|
|
|
if current_user_group_size < smallest_user_group_size:
|
|
|
|
# If multiple user groups are mentioned, we prefer the
|
|
|
|
# user group with the least members.
|
|
|
|
smallest_user_group_size = current_user_group_size
|
|
|
|
smallest_user_group_name = current_user_group.name
|
|
|
|
|
|
|
|
return smallest_user_group_name
|