mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-06-05 01:19:12 -04:00
Implementation for MSC3664: Pushrules for relations (#11804)
This commit is contained in:
parent
c9dffd5b33
commit
2d0ba3f89a
10 changed files with 454 additions and 17 deletions
|
@ -98,6 +98,9 @@ class ExperimentalConfig(Config):
|
|||
# MSC3773: Thread notifications
|
||||
self.msc3773_enabled: bool = experimental.get("msc3773_enabled", False)
|
||||
|
||||
# MSC3664: Pushrules to match on related events
|
||||
self.msc3664_enabled: bool = experimental.get("msc3664_enabled", False)
|
||||
|
||||
# MSC3848: Introduce errcodes for specific event sending failures
|
||||
self.msc3848_enabled: bool = experimental.get("msc3848_enabled", False)
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ if TYPE_CHECKING:
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
push_rules_invalidation_counter = Counter(
|
||||
"synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter", ""
|
||||
)
|
||||
|
@ -107,6 +106,8 @@ class BulkPushRuleEvaluator:
|
|||
self.clock = hs.get_clock()
|
||||
self._event_auth_handler = hs.get_event_auth_handler()
|
||||
|
||||
self._related_event_match_enabled = self.hs.config.experimental.msc3664_enabled
|
||||
|
||||
self.room_push_rule_cache_metrics = register_cache(
|
||||
"cache",
|
||||
"room_push_rule_cache",
|
||||
|
@ -218,6 +219,48 @@ class BulkPushRuleEvaluator:
|
|||
|
||||
return pl_event.content if pl_event else {}, sender_level
|
||||
|
||||
async def _related_events(self, event: EventBase) -> Dict[str, Dict[str, str]]:
|
||||
"""Fetches the related events for 'event'. Sets the im.vector.is_falling_back key if the event is from a fallback relation
|
||||
|
||||
Returns:
|
||||
Mapping of relation type to flattened events.
|
||||
"""
|
||||
related_events: Dict[str, Dict[str, str]] = {}
|
||||
if self._related_event_match_enabled:
|
||||
related_event_id = event.content.get("m.relates_to", {}).get("event_id")
|
||||
relation_type = event.content.get("m.relates_to", {}).get("rel_type")
|
||||
if related_event_id is not None and relation_type is not None:
|
||||
related_event = await self.store.get_event(
|
||||
related_event_id, allow_none=True
|
||||
)
|
||||
if related_event is not None:
|
||||
related_events[relation_type] = _flatten_dict(related_event)
|
||||
|
||||
reply_event_id = (
|
||||
event.content.get("m.relates_to", {})
|
||||
.get("m.in_reply_to", {})
|
||||
.get("event_id")
|
||||
)
|
||||
|
||||
# convert replies to pseudo relations
|
||||
if reply_event_id is not None:
|
||||
related_event = await self.store.get_event(
|
||||
reply_event_id, allow_none=True
|
||||
)
|
||||
|
||||
if related_event is not None:
|
||||
related_events["m.in_reply_to"] = _flatten_dict(related_event)
|
||||
|
||||
# indicate that this is from a fallback relation.
|
||||
if relation_type == "m.thread" and event.content.get(
|
||||
"m.relates_to", {}
|
||||
).get("is_falling_back", False):
|
||||
related_events["m.in_reply_to"][
|
||||
"im.vector.is_falling_back"
|
||||
] = ""
|
||||
|
||||
return related_events
|
||||
|
||||
async def action_for_events_by_user(
|
||||
self, events_and_context: List[Tuple[EventBase, EventContext]]
|
||||
) -> None:
|
||||
|
@ -286,6 +329,8 @@ class BulkPushRuleEvaluator:
|
|||
# the parent is part of a thread.
|
||||
thread_id = await self.store.get_thread_id(relation.parent_id)
|
||||
|
||||
related_events = await self._related_events(event)
|
||||
|
||||
# It's possible that old room versions have non-integer power levels (floats or
|
||||
# strings). Workaround this by explicitly converting to int.
|
||||
notification_levels = power_levels.get("notifications", {})
|
||||
|
@ -298,6 +343,8 @@ class BulkPushRuleEvaluator:
|
|||
room_member_count,
|
||||
sender_power_level,
|
||||
notification_levels,
|
||||
related_events,
|
||||
self._related_event_match_enabled,
|
||||
)
|
||||
|
||||
users = rules_by_user.keys()
|
||||
|
|
|
@ -77,6 +77,11 @@ class CapabilitiesRestServlet(RestServlet):
|
|||
"enabled": True,
|
||||
}
|
||||
|
||||
if self.config.experimental.msc3664_enabled:
|
||||
response["capabilities"]["im.nheko.msc3664.related_event_match"] = {
|
||||
"enabled": self.config.experimental.msc3664_enabled,
|
||||
}
|
||||
|
||||
return HTTPStatus.OK, response
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ from typing import (
|
|||
)
|
||||
|
||||
from synapse.api.errors import StoreError
|
||||
from synapse.config.homeserver import ExperimentalConfig
|
||||
from synapse.replication.slave.storage._slaved_id_tracker import SlavedIdTracker
|
||||
from synapse.storage._base import SQLBaseStore
|
||||
from synapse.storage.database import (
|
||||
|
@ -62,7 +63,9 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def _load_rules(
|
||||
rawrules: List[JsonDict], enabled_map: Dict[str, bool]
|
||||
rawrules: List[JsonDict],
|
||||
enabled_map: Dict[str, bool],
|
||||
experimental_config: ExperimentalConfig,
|
||||
) -> FilteredPushRules:
|
||||
"""Take the DB rows returned from the DB and convert them into a full
|
||||
`FilteredPushRules` object.
|
||||
|
@ -80,7 +83,9 @@ def _load_rules(
|
|||
|
||||
push_rules = PushRules(ruleslist)
|
||||
|
||||
filtered_rules = FilteredPushRules(push_rules, enabled_map)
|
||||
filtered_rules = FilteredPushRules(
|
||||
push_rules, enabled_map, msc3664_enabled=experimental_config.msc3664_enabled
|
||||
)
|
||||
|
||||
return filtered_rules
|
||||
|
||||
|
@ -160,7 +165,7 @@ class PushRulesWorkerStore(
|
|||
|
||||
enabled_map = await self.get_push_rules_enabled_for_user(user_id)
|
||||
|
||||
return _load_rules(rows, enabled_map)
|
||||
return _load_rules(rows, enabled_map, self.hs.config.experimental)
|
||||
|
||||
async def get_push_rules_enabled_for_user(self, user_id: str) -> Dict[str, bool]:
|
||||
results = await self.db_pool.simple_select_list(
|
||||
|
@ -219,7 +224,9 @@ class PushRulesWorkerStore(
|
|||
results: Dict[str, FilteredPushRules] = {}
|
||||
|
||||
for user_id, rules in raw_rules.items():
|
||||
results[user_id] = _load_rules(rules, enabled_map_by_user.get(user_id, {}))
|
||||
results[user_id] = _load_rules(
|
||||
rules, enabled_map_by_user.get(user_id, {}), self.hs.config.experimental
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue