Skip to content

Commit

Permalink
MSC4076: Add disable_badge_count to pusher configuration (#17975)
Browse files Browse the repository at this point in the history
This PR implements [MSC4076: Let E2EE clients calculate app badge counts
themselves
(disable_badge_count)](matrix-org/matrix-spec-proposals#4076).
  • Loading branch information
manuroe authored Dec 3, 2024
1 parent 657dd51 commit abf44ad
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
1 change: 1 addition & 0 deletions changelog.d/17975.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[MSC4076](https://github.com/matrix-org/matrix-spec-proposals/pull/4076): Add `disable_badge_count` to pusher configuration.
3 changes: 3 additions & 0 deletions synapse/config/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,6 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:

# MSC4222: Adding `state_after` to sync v2
self.msc4222_enabled: bool = experimental.get("msc4222_enabled", False)

# MSC4076: Add `disable_badge_count`` to pusher configuration
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
16 changes: 11 additions & 5 deletions synapse/push/httppusher.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ def __init__(self, hs: "HomeServer", pusher_config: PusherConfig):
if self.data is None:
raise PusherConfigException("'data' key can not be null for HTTP pusher")

# Check if badge counts should be disabled for this push gateway
self.disable_badge_count = self.hs.config.experimental.msc4076_enabled and bool(
self.data.get("org.matrix.msc4076.disable_badge_count", False)
)

self.name = "%s/%s/%s" % (
pusher_config.user_name,
pusher_config.app_id,
Expand Down Expand Up @@ -461,9 +466,10 @@ async def dispatch_push_event(
content: JsonDict = {
"event_id": event.event_id,
"room_id": event.room_id,
"counts": {"unread": badge},
"prio": priority,
}
if not self.disable_badge_count:
content["counts"] = {"unread": badge}
# event_id_only doesn't include the tweaks, so override them.
tweaks = {}
else:
Expand All @@ -478,11 +484,11 @@ async def dispatch_push_event(
"type": event.type,
"sender": event.user_id,
"prio": priority,
"counts": {
"unread": badge,
# 'missed_calls': 2
},
}
if not self.disable_badge_count:
content["counts"] = {
"unread": badge,
}
if event.type == "m.room.member" and event.is_state():
content["membership"] = event.content["membership"]
content["user_is_target"] = event.state_key == self.user_id
Expand Down
84 changes: 83 additions & 1 deletion tests/push/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
# [This file includes modifications made by New Vector Limited]
#
#
from typing import Any, List, Tuple
from typing import Any, Dict, List, Tuple
from unittest.mock import Mock

from parameterized import parameterized

from twisted.internet.defer import Deferred
from twisted.test.proto_helpers import MemoryReactor

Expand Down Expand Up @@ -1085,3 +1087,83 @@ def test_jitter(self) -> None:
self.pump()

self.assertEqual(len(self.push_attempts), 11)

@parameterized.expand(
[
# Badge count disabled
(True, True),
(True, False),
# Badge count enabled
(False, True),
(False, False),
]
)
@override_config({"experimental_features": {"msc4076_enabled": True}})
def test_msc4076_badge_count(
self, disable_badge_count: bool, event_id_only: bool
) -> None:
# Register the user who gets notified
user_id = self.register_user("user", "pass")
access_token = self.login("user", "pass")

# Register the user who sends the message
other_user_id = self.register_user("otheruser", "pass")
other_access_token = self.login("otheruser", "pass")

# Register the pusher with disable_badge_count set to True
user_tuple = self.get_success(
self.hs.get_datastores().main.get_user_by_access_token(access_token)
)
assert user_tuple is not None
device_id = user_tuple.device_id

# Set the push data dict based on test input parameters
push_data: Dict[str, Any] = {
"url": "http://example.com/_matrix/push/v1/notify",
}
if disable_badge_count:
push_data["org.matrix.msc4076.disable_badge_count"] = True
if event_id_only:
push_data["format"] = "event_id_only"

self.get_success(
self.hs.get_pusherpool().add_or_update_pusher(
user_id=user_id,
device_id=device_id,
kind="http",
app_id="m.http",
app_display_name="HTTP Push Notifications",
device_display_name="pushy push",
pushkey="[email protected]",
lang=None,
data=push_data,
)
)

# Create a room
room = self.helper.create_room_as(user_id, tok=access_token)

# The other user joins
self.helper.join(room=room, user=other_user_id, tok=other_access_token)

# The other user sends a message
self.helper.send(room, body="Hi!", tok=other_access_token)

# Advance time a bit, so the pusher will register something has happened
self.pump()

# One push was attempted to be sent
self.assertEqual(len(self.push_attempts), 1)
self.assertEqual(
self.push_attempts[0][1], "http://example.com/_matrix/push/v1/notify"
)

if disable_badge_count:
# Verify that the notification DOESN'T contain a counts field
self.assertNotIn("counts", self.push_attempts[0][2]["notification"])
else:
# Ensure that the notification DOES contain a counts field
self.assertIn("counts", self.push_attempts[0][2]["notification"])
self.assertEqual(
self.push_attempts[0][2]["notification"]["counts"]["unread"], 1
)

0 comments on commit abf44ad

Please sign in to comment.