diff --git a/synapse/api/filtering.py b/synapse/api/filtering.py
index c6e44dcf82..cc31cf8cc7 100644
--- a/synapse/api/filtering.py
+++ b/synapse/api/filtering.py
@@ -84,6 +84,7 @@ ROOM_EVENT_FILTER_SCHEMA = {
"contains_url": {"type": "boolean"},
"lazy_load_members": {"type": "boolean"},
"include_redundant_members": {"type": "boolean"},
+ "unread_thread_notifications": {"type": "boolean"},
"org.matrix.msc3773.unread_thread_notifications": {"type": "boolean"},
# Include or exclude events with the provided labels.
# cf https://github.com/matrix-org/matrix-doc/pull/2326
@@ -308,12 +309,16 @@ class Filter:
self.include_redundant_members = filter_json.get(
"include_redundant_members", False
)
- if hs.config.experimental.msc3773_enabled:
- self.unread_thread_notifications: bool = filter_json.get(
+ self.unread_thread_notifications: bool = filter_json.get(
+ "unread_thread_notifications", False
+ )
+ if (
+ not self.unread_thread_notifications
+ and hs.config.experimental.msc3773_enabled
+ ):
+ self.unread_thread_notifications = filter_json.get(
"org.matrix.msc3773.unread_thread_notifications", False
)
- else:
- self.unread_thread_notifications = False
self.types = filter_json.get("types", None)
self.not_types = filter_json.get("not_types", [])
diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py
index 6503ce6e34..c35301207a 100644
--- a/synapse/config/experimental.py
+++ b/synapse/config/experimental.py
@@ -95,8 +95,6 @@ class ExperimentalConfig(Config):
# MSC2815 (allow room moderators to view redacted event content)
self.msc2815_enabled: bool = experimental.get("msc2815_enabled", False)
- # MSC3771: Thread read receipts
- self.msc3771_enabled: bool = experimental.get("msc3771_enabled", False)
# MSC3772: A push rule for mutual relations.
self.msc3772_enabled: bool = experimental.get("msc3772_enabled", False)
# MSC3773: Thread notifications
diff --git a/synapse/handlers/receipts.py b/synapse/handlers/receipts.py
index 4768a34c07..4a7ec9e426 100644
--- a/synapse/handlers/receipts.py
+++ b/synapse/handlers/receipts.py
@@ -63,8 +63,6 @@ class ReceiptsHandler:
self.clock = self.hs.get_clock()
self.state = hs.get_state_handler()
- self._msc3771_enabled = hs.config.experimental.msc3771_enabled
-
async def _received_remote_receipt(self, origin: str, content: JsonDict) -> None:
"""Called when we receive an EDU of type m.receipt from a remote HS."""
receipts = []
@@ -96,11 +94,10 @@ class ReceiptsHandler:
# Check if these receipts apply to a thread.
thread_id = None
data = user_values.get("data", {})
- if self._msc3771_enabled and isinstance(data, dict):
- thread_id = data.get("thread_id")
- # If the thread ID is invalid, consider it missing.
- if not isinstance(thread_id, str):
- thread_id = None
+ thread_id = data.get("thread_id")
+ # If the thread ID is invalid, consider it missing.
+ if not isinstance(thread_id, str):
+ thread_id = None
receipts.append(
ReadReceipt(
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index 0f684857ca..1db5d68021 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -279,8 +279,6 @@ class SyncHandler:
self.rooms_to_exclude = hs.config.server.rooms_to_exclude_from_sync
- self._msc3773_enabled = hs.config.experimental.msc3773_enabled
-
async def wait_for_sync_for_user(
self,
requester: Requester,
@@ -2412,10 +2410,7 @@ class SyncHandler:
unread_count = notifs.main_timeline.unread_count
# Check the sync configuration.
- if (
- self._msc3773_enabled
- and sync_config.filter_collection.unread_thread_notifications()
- ):
+ if sync_config.filter_collection.unread_thread_notifications():
# And add info for each thread.
room_sync.unread_thread_notifications = {
thread_id: {
diff --git a/synapse/rest/client/receipts.py b/synapse/rest/client/receipts.py
index 287dfdd69e..14dec7ac4e 100644
--- a/synapse/rest/client/receipts.py
+++ b/synapse/rest/client/receipts.py
@@ -50,7 +50,6 @@ class ReceiptRestServlet(RestServlet):
ReceiptTypes.READ_PRIVATE,
ReceiptTypes.FULLY_READ,
}
- self._msc3771_enabled = hs.config.experimental.msc3771_enabled
async def on_POST(
self, request: SynapseRequest, room_id: str, receipt_type: str, event_id: str
@@ -67,30 +66,29 @@ class ReceiptRestServlet(RestServlet):
# Pull the thread ID, if one exists.
thread_id = None
- if self._msc3771_enabled:
- if "thread_id" in body:
- thread_id = body.get("thread_id")
- if not thread_id or not isinstance(thread_id, str):
- raise SynapseError(
- 400,
- "thread_id field must be a non-empty string",
- Codes.INVALID_PARAM,
- )
-
- if receipt_type == ReceiptTypes.FULLY_READ:
- raise SynapseError(
- 400,
- f"thread_id is not compatible with {ReceiptTypes.FULLY_READ} receipts.",
- Codes.INVALID_PARAM,
- )
-
- # Ensure the event ID roughly correlates to the thread ID.
- if thread_id != await self._main_store.get_thread_id(event_id):
- raise SynapseError(
- 400,
- f"event_id {event_id} is not related to thread {thread_id}",
- Codes.INVALID_PARAM,
- )
+ if "thread_id" in body:
+ thread_id = body.get("thread_id")
+ if not thread_id or not isinstance(thread_id, str):
+ raise SynapseError(
+ 400,
+ "thread_id field must be a non-empty string",
+ Codes.INVALID_PARAM,
+ )
+
+ if receipt_type == ReceiptTypes.FULLY_READ:
+ raise SynapseError(
+ 400,
+ f"thread_id is not compatible with {ReceiptTypes.FULLY_READ} receipts.",
+ Codes.INVALID_PARAM,
+ )
+
+ # Ensure the event ID roughly correlates to the thread ID.
+ if thread_id != await self._main_store.get_thread_id(event_id):
+ raise SynapseError(
+ 400,
+ f"event_id {event_id} is not related to thread {thread_id}",
+ Codes.INVALID_PARAM,
+ )
await self.presence_handler.bump_presence_active_time(requester.user)
diff --git a/synapse/rest/client/sync.py b/synapse/rest/client/sync.py
index f1c23d68e5..8a16459105 100644
--- a/synapse/rest/client/sync.py
+++ b/synapse/rest/client/sync.py
@@ -100,6 +100,7 @@ class SyncRestServlet(RestServlet):
self._server_notices_sender = hs.get_server_notices_sender()
self._event_serializer = hs.get_event_client_serializer()
self._msc2654_enabled = hs.config.experimental.msc2654_enabled
+ self._msc3773_enabled = hs.config.experimental.msc3773_enabled
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
# This will always be set by the time Twisted calls us.
@@ -510,9 +511,11 @@ class SyncRestServlet(RestServlet):
result["ephemeral"] = {"events": ephemeral_events}
result["unread_notifications"] = room.unread_notifications
if room.unread_thread_notifications:
- result[
- "org.matrix.msc3773.unread_thread_notifications"
- ] = room.unread_thread_notifications
+ result["unread_thread_notifications"] = room.unread_thread_notifications
+ if self._msc3773_enabled:
+ result[
+ "org.matrix.msc3773.unread_thread_notifications"
+ ] = room.unread_thread_notifications
result["summary"] = room.summary
if self._msc2654_enabled:
result["org.matrix.msc2654.unread_count"] = room.unread_count
diff --git a/synapse/rest/client/versions.py b/synapse/rest/client/versions.py
index 18ed313b5c..d1d2e5f7e3 100644
--- a/synapse/rest/client/versions.py
+++ b/synapse/rest/client/versions.py
@@ -105,7 +105,7 @@ class VersionsRestServlet(RestServlet):
# Adds support for thread relations, per MSC3440.
"org.matrix.msc3440.stable": True, # TODO: remove when "v1.3" is added above
# Support for thread read receipts & notification counts.
- "org.matrix.msc3771": self.config.experimental.msc3771_enabled,
+ "org.matrix.msc3771": True,
"org.matrix.msc3773": self.config.experimental.msc3773_enabled,
# Allows moderators to fetch redacted event content as described in MSC2815
"fi.mau.msc2815": self.config.experimental.msc2815_enabled,
|