mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-14 11:57:44 +00:00
Implement MSC3958: suppress notifications from edits (#14960)
Co-authored-by: Brad Murray <brad@beeper.com>
Co-authored-by: Nick Barrett <nick@beeper.com>
Copy the suppress_edits push rule from Beeper to implement MSC3958.
9415a1284b/rust/src/push/base_rules.rs (L98-L114)
This commit is contained in:
parent
e301ee6189
commit
b2d97bac09
9 changed files with 76 additions and 2 deletions
1
changelog.d/14960.feature
Normal file
1
changelog.d/14960.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Experimental support to suppress notifications from message edits ([MSC3958](https://github.com/matrix-org/matrix-spec-proposals/pull/3958)).
|
|
@ -170,6 +170,7 @@ fn bench_eval_message(b: &mut Bencher) {
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
b.iter(|| eval.run(&rules, Some("bob"), Some("person")));
|
b.iter(|| eval.run(&rules, Some("bob"), Some("person")));
|
||||||
|
|
|
@ -63,6 +63,23 @@ pub const BASE_PREPEND_OVERRIDE_RULES: &[PushRule] = &[PushRule {
|
||||||
}];
|
}];
|
||||||
|
|
||||||
pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
|
pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
|
||||||
|
// We don't want to notify on edits. Not only can this be confusing in real
|
||||||
|
// time (2 notifications, one message) but it's especially confusing
|
||||||
|
// if a bridge needs to edit a previously backfilled message.
|
||||||
|
PushRule {
|
||||||
|
rule_id: Cow::Borrowed("global/override/.com.beeper.suppress_edits"),
|
||||||
|
priority_class: 5,
|
||||||
|
conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::EventMatch(
|
||||||
|
EventMatchCondition {
|
||||||
|
key: Cow::Borrowed("content.m.relates_to.rel_type"),
|
||||||
|
pattern: Some(Cow::Borrowed("m.replace")),
|
||||||
|
pattern_type: None,
|
||||||
|
},
|
||||||
|
))]),
|
||||||
|
actions: Cow::Borrowed(&[Action::DontNotify]),
|
||||||
|
default: true,
|
||||||
|
default_enabled: true,
|
||||||
|
},
|
||||||
PushRule {
|
PushRule {
|
||||||
rule_id: Cow::Borrowed("global/override/.m.rule.suppress_notices"),
|
rule_id: Cow::Borrowed("global/override/.m.rule.suppress_notices"),
|
||||||
priority_class: 5,
|
priority_class: 5,
|
||||||
|
|
|
@ -523,7 +523,7 @@ fn test_requires_room_version_supports_condition() {
|
||||||
};
|
};
|
||||||
let rules = PushRules::new(vec![custom_rule]);
|
let rules = PushRules::new(vec![custom_rule]);
|
||||||
result = evaluator.run(
|
result = evaluator.run(
|
||||||
&FilteredPushRules::py_new(rules, BTreeMap::new(), true, false, true, false),
|
&FilteredPushRules::py_new(rules, BTreeMap::new(), true, false, true, false, false),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
|
@ -419,6 +419,7 @@ pub struct FilteredPushRules {
|
||||||
msc3381_polls_enabled: bool,
|
msc3381_polls_enabled: bool,
|
||||||
msc3664_enabled: bool,
|
msc3664_enabled: bool,
|
||||||
msc3952_intentional_mentions: bool,
|
msc3952_intentional_mentions: bool,
|
||||||
|
msc3958_suppress_edits_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
|
@ -431,6 +432,7 @@ impl FilteredPushRules {
|
||||||
msc3381_polls_enabled: bool,
|
msc3381_polls_enabled: bool,
|
||||||
msc3664_enabled: bool,
|
msc3664_enabled: bool,
|
||||||
msc3952_intentional_mentions: bool,
|
msc3952_intentional_mentions: bool,
|
||||||
|
msc3958_suppress_edits_enabled: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
push_rules,
|
push_rules,
|
||||||
|
@ -439,6 +441,7 @@ impl FilteredPushRules {
|
||||||
msc3381_polls_enabled,
|
msc3381_polls_enabled,
|
||||||
msc3664_enabled,
|
msc3664_enabled,
|
||||||
msc3952_intentional_mentions,
|
msc3952_intentional_mentions,
|
||||||
|
msc3958_suppress_edits_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +479,11 @@ impl FilteredPushRules {
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if !self.msc3958_suppress_edits_enabled
|
||||||
|
&& rule.rule_id == "global/override/.com.beeper.suppress_edits"
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
|
|
|
@ -47,6 +47,7 @@ class FilteredPushRules:
|
||||||
msc3381_polls_enabled: bool,
|
msc3381_polls_enabled: bool,
|
||||||
msc3664_enabled: bool,
|
msc3664_enabled: bool,
|
||||||
msc3952_intentional_mentions: bool,
|
msc3952_intentional_mentions: bool,
|
||||||
|
msc3958_suppress_edits_enabled: bool,
|
||||||
): ...
|
): ...
|
||||||
def rules(self) -> Collection[Tuple[PushRule, bool]]: ...
|
def rules(self) -> Collection[Tuple[PushRule, bool]]: ...
|
||||||
|
|
||||||
|
|
|
@ -173,3 +173,8 @@ class ExperimentalConfig(Config):
|
||||||
self.msc3952_intentional_mentions = experimental.get(
|
self.msc3952_intentional_mentions = experimental.get(
|
||||||
"msc3952_intentional_mentions", False
|
"msc3952_intentional_mentions", False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# MSC3959: Do not generate notifications for edits.
|
||||||
|
self.msc3958_supress_edit_notifs = experimental.get(
|
||||||
|
"msc3958_supress_edit_notifs", False
|
||||||
|
)
|
||||||
|
|
|
@ -90,6 +90,7 @@ def _load_rules(
|
||||||
msc3664_enabled=experimental_config.msc3664_enabled,
|
msc3664_enabled=experimental_config.msc3664_enabled,
|
||||||
msc3381_polls_enabled=experimental_config.msc3381_polls_enabled,
|
msc3381_polls_enabled=experimental_config.msc3381_polls_enabled,
|
||||||
msc3952_intentional_mentions=experimental_config.msc3952_intentional_mentions,
|
msc3952_intentional_mentions=experimental_config.msc3952_intentional_mentions,
|
||||||
|
msc3958_suppress_edits_enabled=experimental_config.msc3958_supress_edit_notifs,
|
||||||
)
|
)
|
||||||
|
|
||||||
return filtered_rules
|
return filtered_rules
|
||||||
|
|
|
@ -19,7 +19,7 @@ from parameterized import parameterized
|
||||||
|
|
||||||
from twisted.test.proto_helpers import MemoryReactor
|
from twisted.test.proto_helpers import MemoryReactor
|
||||||
|
|
||||||
from synapse.api.constants import EventContentFields
|
from synapse.api.constants import EventContentFields, RelationTypes
|
||||||
from synapse.api.room_versions import RoomVersions
|
from synapse.api.room_versions import RoomVersions
|
||||||
from synapse.push.bulk_push_rule_evaluator import BulkPushRuleEvaluator
|
from synapse.push.bulk_push_rule_evaluator import BulkPushRuleEvaluator
|
||||||
from synapse.rest import admin
|
from synapse.rest import admin
|
||||||
|
@ -370,3 +370,43 @@ class TestBulkPushRuleEvaluator(HomeserverTestCase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@override_config({"experimental_features": {"msc3958_supress_edit_notifs": True}})
|
||||||
|
def test_suppress_edits(self) -> None:
|
||||||
|
"""Under the default push rules, event edits should not generate notifications."""
|
||||||
|
bulk_evaluator = BulkPushRuleEvaluator(self.hs)
|
||||||
|
|
||||||
|
# Create & persist an event to use as the parent of the relation.
|
||||||
|
event, context = self.get_success(
|
||||||
|
self.event_creation_handler.create_event(
|
||||||
|
self.requester,
|
||||||
|
{
|
||||||
|
"type": "m.room.message",
|
||||||
|
"room_id": self.room_id,
|
||||||
|
"content": {
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"body": "helo",
|
||||||
|
},
|
||||||
|
"sender": self.alice,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.get_success(
|
||||||
|
self.event_creation_handler.handle_new_client_event(
|
||||||
|
self.requester, events_and_context=[(event, context)]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Room mentions from those without power should not notify.
|
||||||
|
self.assertFalse(
|
||||||
|
self._create_and_process(
|
||||||
|
bulk_evaluator,
|
||||||
|
{
|
||||||
|
"body": self.alice,
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": RelationTypes.REPLACE,
|
||||||
|
"event_id": event.event_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue