Skip to content

Commit

Permalink
Add CallNotify event as described by MSC4075
Browse files Browse the repository at this point in the history
See: [MSC4075]( matrix-org/matrix-spec-proposals#4075)

Signed-off-by: Timo K <toger5@hotmail.de>
  • Loading branch information
toger5 committed Nov 22, 2023
1 parent 9728f97 commit 986b14c
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 2 deletions.
1 change: 1 addition & 0 deletions crates/ruma-events/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ unstable-msc3927 = ["unstable-msc3551"]
unstable-msc3954 = ["unstable-msc1767"]
unstable-msc3955 = ["unstable-msc1767"]
unstable-msc3956 = ["unstable-msc1767"]
unstable-msc4075 = []
unstable-pdu = []

# Allow some mandatory fields to be missing, defaulting them to an empty string
Expand Down
2 changes: 2 additions & 0 deletions crates/ruma-events/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub mod invite;
#[cfg(feature = "unstable-msc3401")]
pub mod member;
pub mod negotiate;
#[cfg(feature = "unstable-msc4075")]
pub mod notify;
pub mod reject;
pub mod select_answer;

Expand Down
77 changes: 77 additions & 0 deletions crates/ruma-events/src/call/notify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//! Types for matrixRTC call notify event ([MSC4075]).
//!
//! This implements the event type defined in MSC4075.
//!
//! [MSC3401]: https://github.com/matrix-org/matrix-spec-proposals/pull/4075

use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};

use super::member::Application;
use crate::Mentions;

/// The content of an `m.call.notify` event.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.call.notify", kind = MessageLike)]
pub struct CallNotifyEventContent {
/// A unique identifier for the call.
pub call_id: String,
/// The application this notify event applies to.
pub application: ApplicationType,
/// How this notify event should notify the receiver.
pub notify_type: NotifyType,
/// The users that are notified by this event (See [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952)(Intentional Mentions)).
#[serde(rename = "m.mentions")]
pub mentions: Mentions,
}

impl CallNotifyEventContent {
/// Creates a new `CallNotifyEventContent` with the given configuration.
pub fn new(
call_id: String,
application: ApplicationType,
notify_type: NotifyType,
mentions: Mentions,
) -> Self {
Self { call_id, application, notify_type, mentions }
}
}

/// How this notify event should notify the receiver.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum NotifyType {
/// The receiving client should ring with an audible sound.
#[serde(rename = "ring")]
Ring,
/// The receiving client should display a visual notification.
#[serde(rename = "notify")]
Notify,
}

/// The type of matrix RTC application.
///
/// This is different to [`Application`] because application contains all the information from the
/// call.member event.
///
/// An `Application` can be converted into an `ApplicationType`:
/// ```
/// let a: Application = myApp;
/// let b: ApplicationType = a.into();
/// ```
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum ApplicationType {
/// A VoIP call.
#[serde(rename = "m.call")]
Call,
}

impl From<Application> for ApplicationType {
fn from(val: Application) -> Self {
match val {
Application::Call(_) => ApplicationType::Call,
}
}
}
4 changes: 4 additions & 0 deletions crates/ruma-events/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ event_enum! {
#[cfg(feature = "unstable-msc3245")]
#[ruma_enum(alias = "m.voice")]
"org.matrix.msc3245.voice.v2" => super::voice,
#[cfg(feature = "unstable-msc4075")]
#[ruma_enum(alias = "m.call.notify")]
"org.matrix.msc4075.call.notify" => super::call::notify,
}

/// Any state event.
Expand Down Expand Up @@ -361,6 +364,7 @@ impl AnyMessageLikeEventContent {
| Self::CallCandidates(_)
| Self::RoomRedaction(_)
| Self::Sticker(_)
| Self::CallNotify(_)
| Self::_Custom { .. } => None,
}
}
Expand Down
79 changes: 77 additions & 2 deletions crates/ruma-events/tests/it/call.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::collections::BTreeSet;

use assert_matches2::assert_matches;
#[cfg(feature = "unstable-msc2747")]
use assign::assign;
use js_int::uint;
use ruma_common::{room_id, serde::CanBeEmpty, MilliSecondsSinceUnixEpoch, VoipVersionId};
use ruma_common::{room_id, serde::CanBeEmpty, MilliSecondsSinceUnixEpoch, UserId, VoipVersionId};
#[cfg(feature = "unstable-msc2747")]
use ruma_events::call::CallCapabilities;
use ruma_events::{
Expand All @@ -12,11 +14,12 @@ use ruma_events::{
hangup::{CallHangupEventContent, Reason},
invite::CallInviteEventContent,
negotiate::CallNegotiateEventContent,
notify::{ApplicationType, CallNotifyEventContent, NotifyType},
reject::CallRejectEventContent,
select_answer::CallSelectAnswerEventContent,
SessionDescription,
},
AnyMessageLikeEvent, AnySyncMessageLikeEvent, MessageLikeEvent,
AnyMessageLikeEvent, AnySyncMessageLikeEvent, Mentions, MessageLikeEvent,
};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

Expand Down Expand Up @@ -598,3 +601,75 @@ fn select_v1_answer_event_deserialization() {
assert_eq!(content.selected_party_id, "6336");
assert_eq!(content.version, VoipVersionId::V1);
}

#[test]
fn notify_event_serialization() {
let content_user_mention = CallNotifyEventContent::new(
"abcdef".into(),
ApplicationType::Call,
NotifyType::Ring,
Mentions::with_user_ids(vec![
<&UserId>::try_from("@user:example.com").unwrap().into(),
<&UserId>::try_from("@user2:example.com").unwrap().into(),
]),
);

let content_room_mention = CallNotifyEventContent::new(
"abcdef".into(),
ApplicationType::Call,
NotifyType::Ring,
Mentions::with_room_mention(),
);

assert_eq!(
to_json_value(&content_user_mention).unwrap(),
json!({
"call_id": "abcdef",
"application": "m.call",
"m.mentions": {"user_ids": ["@user2:example.com","@user:example.com"]},
"notify_type": "ring",
})
);
assert_eq!(
to_json_value(&content_room_mention).unwrap(),
json!({
"call_id": "abcdef",
"application": "m.call",
"m.mentions": {"room": true},
"notify_type": "ring",
})
);
}

#[test]
fn notify_event_deserialization() {
let json_data = json!({
"content": {
"call_id": "abcdef",
"application": "m.call",
"m.mentions": {"room": false, "user_ids": ["@user:example.com", "@user2:example.com"]},
"notify_type": "ring",
},
"event_id": "$event:notareal.hs",
"origin_server_ts": 134_829_848,
"room_id": "!roomid:notareal.hs",
"sender": "@user:notareal.hs",
"type": "m.call.notify",
});

let event = from_json_value::<AnyMessageLikeEvent>(json_data).unwrap();
assert_matches!(
event,
AnyMessageLikeEvent::CallNotify(MessageLikeEvent::Original(message_event))
);
let content = message_event.content;
assert_eq!(content.call_id, "abcdef");
assert!(!content.mentions.room);
assert_eq!(
content.mentions.user_ids,
BTreeSet::from([
<&UserId>::try_from("@user:example.com").unwrap().to_owned(),
<&UserId>::try_from("@user2:example.com").unwrap().to_owned(),
])
);
}
2 changes: 2 additions & 0 deletions crates/ruma/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ unstable-msc3955 = ["ruma-events?/unstable-msc3955"]
unstable-msc3956 = ["ruma-events?/unstable-msc3956"]
unstable-msc3958 = ["ruma-common/unstable-msc3958"]
unstable-msc3983 = ["ruma-client-api?/unstable-msc3983"]
unstable-msc4075 = ["ruma-events?/unstable-msc4075"]
unstable-pdu = ["ruma-events?/unstable-pdu"]
unstable-unspecified = [
"ruma-common/unstable-unspecified",
Expand Down Expand Up @@ -259,6 +260,7 @@ __ci = [
"unstable-msc3956",
"unstable-msc3958",
"unstable-msc3983",
"unstable-msc4075",
]

[dependencies]
Expand Down

0 comments on commit 986b14c

Please sign in to comment.