ruma_events/call/
notify.rs

1//! Type for the MatrixRTC notify event ([MSC4075]).
2//!
3//! [MSC4075]: https://github.com/matrix-org/matrix-spec-proposals/pull/4075
4
5use ruma_macros::EventContent;
6use serde::{Deserialize, Serialize};
7
8use super::member::Application;
9use crate::{Mentions, rtc};
10
11/// The content of an `m.call.notify` event.
12#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
13#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
14#[ruma_event(type = "m.call.notify", kind = MessageLike)]
15#[deprecated = "Use the m.rtc.notification event instead."]
16pub struct CallNotifyEventContent {
17    /// A unique identifier for the call.
18    pub call_id: String,
19
20    /// The application this notify event applies to.
21    pub application: ApplicationType,
22
23    /// How this notify event should notify the receiver.
24    pub notify_type: rtc::notification::NotificationType,
25
26    /// The users that are notified by this event (See [MSC3952] (Intentional Mentions)).
27    ///
28    /// [MSC3952]: https://github.com/matrix-org/matrix-spec-proposals/pull/3952
29    #[serde(rename = "m.mentions")]
30    pub mentions: Mentions,
31}
32impl CallNotifyEventContent {
33    /// Creates a new `CallNotifyEventContent` with the given configuration.
34    pub fn new(
35        call_id: String,
36        application: ApplicationType,
37        notify_type: rtc::notification::NotificationType,
38        mentions: Mentions,
39    ) -> Self {
40        Self { call_id, application, notify_type, mentions }
41    }
42}
43
44/// The type of matrix RTC application.
45///
46/// This is different to [`Application`] because application contains all the information from the
47/// `m.call.member` event.
48///
49/// An `Application` can be converted into an `ApplicationType` using `.into()`.
50#[derive(Clone, Debug, Deserialize, Serialize)]
51#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
52#[deprecated = "Part of the deprecated CallNotifyEventContent."]
53pub enum ApplicationType {
54    /// A VoIP call.
55    #[serde(rename = "m.call")]
56    Call,
57}
58
59impl From<Application> for ApplicationType {
60    fn from(val: Application) -> Self {
61        match val {
62            Application::Call(_) => ApplicationType::Call,
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use ruma_common::canonical_json::assert_to_canonical_json_eq;
70    use serde_json::{from_value as from_json_value, json};
71
72    use crate::{
73        Mentions,
74        call::notify::{ApplicationType, CallNotifyEventContent},
75        rtc,
76    };
77
78    #[test]
79    fn notify_event_serialization() {
80        use ruma_common::owned_user_id;
81
82        let content_user_mention = CallNotifyEventContent::new(
83            "abcdef".into(),
84            ApplicationType::Call,
85            rtc::notification::NotificationType::Ring,
86            Mentions::with_user_ids(vec![
87                owned_user_id!("@user:example.com"),
88                owned_user_id!("@user2:example.com"),
89            ]),
90        );
91
92        let content_room_mention = CallNotifyEventContent::new(
93            "abcdef".into(),
94            ApplicationType::Call,
95            rtc::notification::NotificationType::Ring,
96            Mentions::with_room_mention(),
97        );
98
99        assert_to_canonical_json_eq!(
100            content_user_mention,
101            json!({
102                "call_id": "abcdef",
103                "application": "m.call",
104                "m.mentions": {
105                    "user_ids": ["@user2:example.com","@user:example.com"],
106                },
107                "notify_type": "ring",
108            })
109        );
110        assert_to_canonical_json_eq!(
111            content_room_mention,
112            json!({
113                "call_id": "abcdef",
114                "application": "m.call",
115                "m.mentions": { "room": true },
116                "notify_type": "ring",
117            })
118        );
119    }
120
121    #[test]
122    fn notify_event_deserialization() {
123        use std::collections::BTreeSet;
124
125        use assert_matches2::assert_matches;
126        use ruma_common::owned_user_id;
127
128        use crate::{AnyMessageLikeEvent, MessageLikeEvent};
129
130        let json_data = json!({
131            "content": {
132                "call_id": "abcdef",
133                "application": "m.call",
134                "m.mentions": {
135                    "room": false,
136                    "user_ids": ["@user:example.com", "@user2:example.com"],
137                },
138                "notify_type": "ring",
139            },
140            "event_id": "$event:notareal.hs",
141            "origin_server_ts": 134_829_848,
142            "room_id": "!roomid:notareal.hs",
143            "sender": "@user:notareal.hs",
144            "type": "m.call.notify",
145        });
146
147        let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
148        assert_matches!(
149            event,
150            AnyMessageLikeEvent::CallNotify(MessageLikeEvent::Original(message_event))
151        );
152        let content = message_event.content;
153        assert_eq!(content.call_id, "abcdef");
154        assert!(!content.mentions.room);
155        assert_eq!(
156            content.mentions.user_ids,
157            BTreeSet::from([
158                owned_user_id!("@user:example.com"),
159                owned_user_id!("@user2:example.com")
160            ])
161        );
162    }
163}