Skip to main content

matrix_sdk_base/response_processors/
notification.rs

1// Copyright 2025 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::BTreeMap;
16
17use ruma::{
18    OwnedRoomId,
19    push::{Action, PushConditionRoomCtx, Ruleset},
20    serde::Raw,
21};
22
23use crate::{
24    deserialized_responses::RawAnySyncOrStrippedTimelineEvent, store::BaseStateStore, sync,
25};
26
27/// A classical set of data used by some processors dealing with notifications
28/// and push rules.
29pub struct Notification<'a> {
30    pub push_rules: &'a Ruleset,
31    pub notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
32    pub state_store: &'a BaseStateStore,
33}
34
35impl<'a> Notification<'a> {
36    pub fn new(
37        push_rules: &'a Ruleset,
38        notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
39        state_store: &'a BaseStateStore,
40    ) -> Self {
41        Self { push_rules, notifications, state_store }
42    }
43
44    fn push_notification(
45        &mut self,
46        room_id: OwnedRoomId,
47        actions: Vec<Action>,
48        event: RawAnySyncOrStrippedTimelineEvent,
49    ) {
50        self.notifications.entry(room_id).or_default().push(sync::Notification { actions, event });
51    }
52
53    /// Push a new [`sync::Notification`] in [`Self::notifications`] from
54    /// `event` if and only if `predicate` returns `true` for at least one of
55    /// the [`Action`]s associated to this event and this
56    /// `push_condition_room_ctx`. (based on [`Self::push_rules`]).
57    ///
58    /// This method returns the fetched [`Action`]s.
59    pub async fn push_notification_from_event_if<E, P>(
60        &mut self,
61        push_condition_room_ctx: &PushConditionRoomCtx,
62        event: &Raw<E>,
63        predicate: P,
64    ) -> &[Action]
65    where
66        Raw<E>: Into<RawAnySyncOrStrippedTimelineEvent>,
67        P: Fn(&Action) -> bool,
68    {
69        let actions = self.push_rules.get_actions(event, push_condition_room_ctx).await;
70
71        if actions.iter().any(predicate) {
72            self.push_notification(
73                push_condition_room_ctx.room_id.clone(),
74                actions.to_owned(),
75                event.clone().into(),
76            );
77        }
78
79        actions
80    }
81}