From c9355e1c1e0fc67f6d20cef3ef4bd7757e05d6fb Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 8 Nov 2023 17:55:05 +0100 Subject: [PATCH 01/12] add initial msc for call ringing Signed-off-by: Timo K --- proposals/XXX-call-notify-event.md | 86 ++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 proposals/XXX-call-notify-event.md diff --git a/proposals/XXX-call-notify-event.md b/proposals/XXX-call-notify-event.md new file mode 100644 index 00000000000..91a5d9d53fc --- /dev/null +++ b/proposals/XXX-call-notify-event.md @@ -0,0 +1,86 @@ +# MSC0000: MatrixRTC Call Ringing +It is important that a call initiated on clientA can make targeted clients ring. +This is of interest in 1:1 Rooms/Calls but also in bigger rooms ringing can be desired. + +Legacy calls are using room events to negotiate the call. A client could use the initial steps in the negotiation to also make the phone ring. + +With matrix RTC based calls this signalling is done over state events. Also matrix RTC enables large group calls which makes it very desirable to have more configurations over the ringing process. + +## Proposal + +A new event `m.call.notify` is proposed which can be sent by a client that wants to start a call. +This event is added to the push rules for clients which support calling so they get push notifications. The push rules for intentional mentions make sure no unnecessary push notification is sent. + +This event contains the following fields by leveraging intentional mentions. + +```json +{ + "content": { + "application": "m.call" | "m.other_matrix_session_type" | "...", + "m.mentions": {"user_ids": [], "room": true | false}, + "notify_type": "ring" | "notification", + // Application specific data, + // optional fields to disambiguate which session + // this notify event belongs to: + + // for application = "m.call": + "call_id": "some_id", + } +} +``` + +In the following we define **call** as any matrix RTC session with the same `"application"` and the same application specific data. In the calse of `"m.call"`, the same `"call_id"`. + +On retrieval, the event should not be rendered in the timeline. But if the notify conditions (listed below) apply, the client has to inform the user about the **call** with an appropriate user flow. +For `notify_by == "ring"` some kind of sound is required (except if overwritten by another client specific setting), +for `notify_by == "notification"` a visual indication is enough. This visual indication should be more than an unread indicator and similar to a notification banner. This is not enforced by the spec however and ultimately a client choice. + +Notify conditions depend on:\ +(here we use ) + - `m.call.notify` content:\ + If the user is not part of the `m.mentions` section as defined in [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) this event can be ignored. (Push notifications are automatically filtered so this only is important for events received via a sync) + - Local notification settings:\ + If the room is set to silent, it will never play a ring sound. A `m.call.notify` event will at most be used to mark the room as unread or update the rooms "has active **call** icon". (the exact behavior is up to the client) + - Currently playing a ring sound (room timeline):\ + If the user already received a ring event for this **call** and is playing the ring sound any incoming `m.call.notify` for the same **call** should be ignored. If the user failed to pick up and a new `m.call.notify` arrives for the same room the device should ring again. + - Current user is a member of the the **call** (room state):\ + None of the devices should ring if they receive a `m.call.notify` if the rooms state `m.call.member` event of the user contains a membership for the **call** in the `m.call.notify` event. + This includes stopping the current ring sound if the room state updates so this condition is true. + +Sending a `m.call.notify` should happen if all of these conditions apply: + - If the user deliberately wants to send a new notify event (It is possible to send a `m.call.notify` for an ongoing call if that makes sense. Starting a call ahead of time, planning in a small group, ringing another set of users at a specific time so they don't forget to join. Ringing one specific user again who missed joining during the first ring.) + - If the user has not yet received a `m.call.notify` for the **call** they want to participate but the other condition applies. (So the obvious case is, that this is the first user in a new call session). + + +## Potential issues + + +## Alternatives + +It would be possible to use the call member room state events to determine a call start. +The logic would be as following: + +*If we receive an event we check if there is are already other members (call.member events) for the call. In case there is not we make the phone ring.* + +Pros: + - This would not require any new event. + - The clients can not "forget" to ring the others about the when they start a new call. Because they would automatically send an event by joining. + - There would be less traffic. With the proposed solution the first one who joins needs to send a `m.call.notify` event and a `m.call.member` state event. + - Very flexible, since the `m.call.notify` event is separate from a call participation. This allows an external instance (a meeting organizer bot) to just ring all the users which are invited to a meeting without needing to be part of the call. + +Cons + - All the ringing conditions run on the receiving user. There is no way for the user who start the call to decide if it should ring the other participants. (Consider a very large room where I want to start a call only for the interested ones who want to discuss a side project. It would be very annoying if the initiator could not control how and who is going to be informed about that call.) + - Push notifications would need to be sent for EVERY `m.call.member` state event update. For each joining and leaving user and for each membership update during a call (due to a SFU (single forwarding unit) change, changing devices (could even happen for screen shares if the screen share is implemented as a separate participating device) or matrix RTC business logic of the call.) - This could result in a lot of push notification with no obvious/simple way to filter them. + - It would require bloating the `call.member` event if the `notify_type` or a specific list of users to notify want to be specified. + - It would not make it possible to ring without participating. + +## Security considerations +This is another timeline event where any room participant can send a push notification to others. Since this will make clients ring this has a higher effect on the receiver. Since ringing has to obey the mute settings, it is very easy for the targeted users to mitigate the "attack". It can be very much compared to spamming a room with "@room" messages. + +## Unstable prefix +While this MSC is not present in the spec, clients and widgets should: + - Use org.matrix.mscXXXX. in place of m. in all new identifiers of this MSC. (`m.call.notify`) + +## Dependencies + +This MSC builds on Intentional Mentions [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952). From ed894b3a8ccbe45683d87cd5be2c013205b7c548 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 8 Nov 2023 17:56:23 +0100 Subject: [PATCH 02/12] update msc number Signed-off-by: Timo K --- .../{XXX-call-notify-event.md => 4075-call-notify-event.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename proposals/{XXX-call-notify-event.md => 4075-call-notify-event.md} (97%) diff --git a/proposals/XXX-call-notify-event.md b/proposals/4075-call-notify-event.md similarity index 97% rename from proposals/XXX-call-notify-event.md rename to proposals/4075-call-notify-event.md index 91a5d9d53fc..4e1af0a3aad 100644 --- a/proposals/XXX-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -1,4 +1,4 @@ -# MSC0000: MatrixRTC Call Ringing +# MSC4075: MatrixRTC Call Ringing It is important that a call initiated on clientA can make targeted clients ring. This is of interest in 1:1 Rooms/Calls but also in bigger rooms ringing can be desired. @@ -29,7 +29,7 @@ This event contains the following fields by leveraging intentional mentions. } ``` -In the following we define **call** as any matrix RTC session with the same `"application"` and the same application specific data. In the calse of `"m.call"`, the same `"call_id"`. +In the following we define **call** as any matrix RTC session with the same `"application"` and the same application specific data. In the case of `"m.call"`, the same `"call_id"`. On retrieval, the event should not be rendered in the timeline. But if the notify conditions (listed below) apply, the client has to inform the user about the **call** with an appropriate user flow. For `notify_by == "ring"` some kind of sound is required (except if overwritten by another client specific setting), @@ -79,7 +79,7 @@ This is another timeline event where any room participant can send a push notifi ## Unstable prefix While this MSC is not present in the spec, clients and widgets should: - - Use org.matrix.mscXXXX. in place of m. in all new identifiers of this MSC. (`m.call.notify`) + - Use org.matrix.msc4075. in place of m. in all new identifiers of this MSC. (`m.call.notify`) ## Dependencies From ce551cb02a384dde91a14058a0bb47c861701c9f Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 8 Nov 2023 17:59:09 +0100 Subject: [PATCH 03/12] json->plaintext for example Signed-off-by: Timo K --- proposals/4075-call-notify-event.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 4e1af0a3aad..7ebc5337c8a 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -13,7 +13,7 @@ This event is added to the push rules for clients which support calling so they This event contains the following fields by leveraging intentional mentions. -```json +``` { "content": { "application": "m.call" | "m.other_matrix_session_type" | "...", From 49190d1b6fc6849d6876d89330bed0c7ecd768cb Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 8 Nov 2023 19:33:05 +0100 Subject: [PATCH 04/12] markdown lint Signed-off-by: Timo K --- proposals/4075-call-notify-event.md | 124 ++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 34 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 7ebc5337c8a..9a8a8e1420b 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -1,15 +1,21 @@ # MSC4075: MatrixRTC Call Ringing + It is important that a call initiated on clientA can make targeted clients ring. This is of interest in 1:1 Rooms/Calls but also in bigger rooms ringing can be desired. -Legacy calls are using room events to negotiate the call. A client could use the initial steps in the negotiation to also make the phone ring. +Legacy calls are using room events to negotiate the call. +A client could use the initial steps in the negotiation to also make the phone ring. -With matrix RTC based calls this signalling is done over state events. Also matrix RTC enables large group calls which makes it very desirable to have more configurations over the ringing process. +With matrix RTC based calls this signalling is done over state events. +Also matrix RTC enables large group calls which makes it very +desirable to have more configurations over the ringing process. ## Proposal -A new event `m.call.notify` is proposed which can be sent by a client that wants to start a call. -This event is added to the push rules for clients which support calling so they get push notifications. The push rules for intentional mentions make sure no unnecessary push notification is sent. +A new event `m.call.notify` is proposed which can be sent by a client that +wants to start a call. This event is added to the push rules for clients which +support calling so they get push notifications. The push rules for intentional +mentions make sure no unnecessary push notification is sent. This event contains the following fields by leveraging intentional mentions. @@ -20,7 +26,7 @@ This event contains the following fields by leveraging intentional mentions. "m.mentions": {"user_ids": [], "room": true | false}, "notify_type": "ring" | "notification", // Application specific data, - // optional fields to disambiguate which session + // optional fields to disambiguate which session // this notify event belongs to: // for application = "m.call": @@ -29,57 +35,107 @@ This event contains the following fields by leveraging intentional mentions. } ``` -In the following we define **call** as any matrix RTC session with the same `"application"` and the same application specific data. In the case of `"m.call"`, the same `"call_id"`. +In the following we define **call** as any matrix RTC session with the +same `"application"` and the same application specific data. +In the case of `"m.call"`, the same `"call_id"`. -On retrieval, the event should not be rendered in the timeline. But if the notify conditions (listed below) apply, the client has to inform the user about the **call** with an appropriate user flow. -For `notify_by == "ring"` some kind of sound is required (except if overwritten by another client specific setting), -for `notify_by == "notification"` a visual indication is enough. This visual indication should be more than an unread indicator and similar to a notification banner. This is not enforced by the spec however and ultimately a client choice. +On retrieval, the event should not be rendered in the timeline. +But if the notify conditions (listed below) apply, +the client has to inform the user about the **call** with an appropriate user flow. +For `notify_by == "ring"` some kind of sound is required +(except if overwritten by another client specific setting), +for `notify_by == "notification"` a visual indication is enough. +This visual indication should be more than an unread indicator +and similar to a notification banner. +This is not enforced by the spec however and ultimately a client choice. Notify conditions depend on:\ (here we use ) - - `m.call.notify` content:\ - If the user is not part of the `m.mentions` section as defined in [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) this event can be ignored. (Push notifications are automatically filtered so this only is important for events received via a sync) - - Local notification settings:\ - If the room is set to silent, it will never play a ring sound. A `m.call.notify` event will at most be used to mark the room as unread or update the rooms "has active **call** icon". (the exact behavior is up to the client) - - Currently playing a ring sound (room timeline):\ - If the user already received a ring event for this **call** and is playing the ring sound any incoming `m.call.notify` for the same **call** should be ignored. If the user failed to pick up and a new `m.call.notify` arrives for the same room the device should ring again. - - Current user is a member of the the **call** (room state):\ - None of the devices should ring if they receive a `m.call.notify` if the rooms state `m.call.member` event of the user contains a membership for the **call** in the `m.call.notify` event. - This includes stopping the current ring sound if the room state updates so this condition is true. - -Sending a `m.call.notify` should happen if all of these conditions apply: - - If the user deliberately wants to send a new notify event (It is possible to send a `m.call.notify` for an ongoing call if that makes sense. Starting a call ahead of time, planning in a small group, ringing another set of users at a specific time so they don't forget to join. Ringing one specific user again who missed joining during the first ring.) - - If the user has not yet received a `m.call.notify` for the **call** they want to participate but the other condition applies. (So the obvious case is, that this is the first user in a new call session). +- `m.call.notify` content:\ + If the user is not part of the `m.mentions` section as defined in + [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) + this event can be ignored. (Push notifications are automatically filtered + so this only is important for events received via a sync) +- Local notification settings:\ + If the room is set to silent, it will never play a ring sound. A `m.call.notify` + event will at most be used to mark the room as unread or update the rooms + "has active **call** icon". (the exact behavior is up to the client) +- Currently playing a ring sound (room timeline):\ + If the user already received a ring event for this **call** and is playing + the ring sound any incoming `m.call.notify` for the same **call** + should be ignored. If the user failed to pick up and a new `m.call.notify` + arrives for the same room the device should ring again. +- Current user is a member of the the **call** (room state):\ + None of the devices should ring if they receive a `m.call.notify` if the + rooms state `m.call.member` event of the user contains a membership for + the **call** in the `m.call.notify` event. + This includes stopping the current ring sound if the room state updates so + this condition is true. -## Potential issues +Sending a `m.call.notify` should happen if all of these conditions apply: +- If the user deliberately wants to send a new notify event + (It is possible to send a `m.call.notify` for an ongoing call if that + makes sense. Starting a call ahead of time, planning in a small group, + ringing another set of users at a specific time so they don't forget to join. + Ringing one specific user again who missed joining during the first ring.) +- If the user has not yet received a `m.call.notify` for the **call** they want to + participate but the other condition applies. (So the obvious case is, that this + is the first user in a new call session). ## Alternatives It would be possible to use the call member room state events to determine a call start. The logic would be as following: -*If we receive an event we check if there is are already other members (call.member events) for the call. In case there is not we make the phone ring.* +_If we receive an event we check if there is are already other members +(call.member events) for the call. In case there is not we make the phone ring._ Pros: - - This would not require any new event. - - The clients can not "forget" to ring the others about the when they start a new call. Because they would automatically send an event by joining. - - There would be less traffic. With the proposed solution the first one who joins needs to send a `m.call.notify` event and a `m.call.member` state event. - - Very flexible, since the `m.call.notify` event is separate from a call participation. This allows an external instance (a meeting organizer bot) to just ring all the users which are invited to a meeting without needing to be part of the call. + +- This would not require any new event. +- The clients can not "forget" to ring the others about the when they + start a new call. Because they would automatically send an event by joining. +- There would be less traffic. With the proposed solution the first one who joins + needs to send a `m.call.notify` event and a `m.call.member` state event. +- Very flexible, since the `m.call.notify` event is separate from a call + participation. This allows an external instance (a meeting organizer bot) to + just ring all the users which are invited to a meeting without needing to be + part of the call. Cons - - All the ringing conditions run on the receiving user. There is no way for the user who start the call to decide if it should ring the other participants. (Consider a very large room where I want to start a call only for the interested ones who want to discuss a side project. It would be very annoying if the initiator could not control how and who is going to be informed about that call.) - - Push notifications would need to be sent for EVERY `m.call.member` state event update. For each joining and leaving user and for each membership update during a call (due to a SFU (single forwarding unit) change, changing devices (could even happen for screen shares if the screen share is implemented as a separate participating device) or matrix RTC business logic of the call.) - This could result in a lot of push notification with no obvious/simple way to filter them. - - It would require bloating the `call.member` event if the `notify_type` or a specific list of users to notify want to be specified. - - It would not make it possible to ring without participating. + +- All the ringing conditions run on the receiving user. There is no way for the + user who start the call to decide if it should ring the other participants. + (Consider a very large room where I want to start a call only for the interested + ones who want to discuss a side project. It would be very annoying if the + initiator could not control how and who is going to be informed about that call.) +- Push notifications would need to be sent for EVERY `m.call.member` state event + update. For each joining and leaving user and for each membership update during + a call (due to a SFU (single forwarding unit) change, changing devices + (could even happen for screen shares if the screen share is implemented as a + separate participating device) or matrix RTC business logic of the call.) + This could result in a lot of push notification with no obvious/simple way to + filter them. +- It would require bloating the `call.member` event if the `notify_type` or a + specific list of users to notify want to be specified. +- It would not make it possible to ring without participating. ## Security considerations -This is another timeline event where any room participant can send a push notification to others. Since this will make clients ring this has a higher effect on the receiver. Since ringing has to obey the mute settings, it is very easy for the targeted users to mitigate the "attack". It can be very much compared to spamming a room with "@room" messages. + +This is another timeline event where any room participant can send a push +notification to others. Since this will make clients ring this has a higher +effect on the receiver. Since ringing has to obey the mute settings, it is +very easy for the targeted users to mitigate the "attack". It can be very +much compared to spamming a room with "@room" messages. ## Unstable prefix + While this MSC is not present in the spec, clients and widgets should: - - Use org.matrix.msc4075. in place of m. in all new identifiers of this MSC. (`m.call.notify`) + +- Use `org.matrix.msc4075.` in place of `m.` in all new identifiers of this MSC. +(`m.call.notify`) ## Dependencies From 1cecf69c927dcfd3bf914fa68b2c03d41fddb6d3 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 9 Nov 2023 12:25:25 +0100 Subject: [PATCH 05/12] review changes Signed-off-by: Timo K --- proposals/4075-call-notify-event.md | 42 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 9a8a8e1420b..192d91e76dd 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -22,9 +22,9 @@ This event contains the following fields by leveraging intentional mentions. ``` { "content": { - "application": "m.call" | "m.other_matrix_session_type" | "...", + "application": "m.call | m.other_matrix_session_type | ...", "m.mentions": {"user_ids": [], "room": true | false}, - "notify_type": "ring" | "notification", + "notify_type": "ring | notification", // Application specific data, // optional fields to disambiguate which session // this notify event belongs to: @@ -49,31 +49,37 @@ This visual indication should be more than an unread indicator and similar to a notification banner. This is not enforced by the spec however and ultimately a client choice. -Notify conditions depend on:\ -(here we use ) +Ringing (or notifying) should happen only if all these conditions apply:\ - `m.call.notify` content:\ - If the user is not part of the `m.mentions` section as defined in + If the user is not part of the `m.mentions` section as defined in [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) this event can be ignored. (Push notifications are automatically filtered so this only is important for events received via a sync) - Local notification settings:\ - If the room is set to silent, it will never play a ring sound. A `m.call.notify` + If the room is set to silent, it will never play a ring sound. A `m.call.notify` event will at most be used to mark the room as unread or update the rooms "has active **call** icon". (the exact behavior is up to the client) - Currently playing a ring sound (room timeline):\ - If the user already received a ring event for this **call** and is playing + If the user already received a ring event for this **call** and is playing the ring sound any incoming `m.call.notify` for the same **call** should be ignored. If the user failed to pick up and a new `m.call.notify` arrives for the same room the device should ring again. - Current user is a member of the the **call** (room state):\ - None of the devices should ring if they receive a `m.call.notify` if the + None of the devices should ring if they receive a `m.call.notify` if the rooms state `m.call.member` event of the user contains a membership for the **call** in the `m.call.notify` event. This includes stopping the current ring sound if the room state updates so this condition is true. +- If a notify event is received in "real time":\ + Notify events that are older then **10 seconds** are ignored (using the local + timestamp computed via `unsigned.age`).\ + Otherwise a clients syncing for the first time would ring for outdated call events. + In general ringing only makes sense in "real time". A 10 second syncing latency + is allowed. Any client which is not able to receive the event in this period should + not ring to prohibit (annoying/misleading/irrelevant) outdated rings. -Sending a `m.call.notify` should happen if all of these conditions apply: +Sending a `m.call.notify` should happen only if all of these conditions apply: - If the user deliberately wants to send a new notify event (It is possible to send a `m.call.notify` for an ongoing call if that @@ -122,6 +128,15 @@ Cons specific list of users to notify want to be specified. - It would not make it possible to ring without participating. +### Explicitly unspecified conditions + +- The duration of the ring sound is a deliberately chosen + to be a clients decision. +- The ring sound is a client choice as well. (It was considered to + add the ring sound to the notify event but how "ringing" actually should + look like is intentionally in control of the receiver. So that users can use + clients that suit them in terms of accessibility and personal taste.) + ## Security considerations This is another timeline event where any room participant can send a push @@ -130,11 +145,18 @@ effect on the receiver. Since ringing has to obey the mute settings, it is very easy for the targeted users to mitigate the "attack". It can be very much compared to spamming a room with "@room" messages. +The default power level for `m.call.notify` is `50` and equivalent to the default +power level required for `m.call.member` state events. + +Additional control is provided indirectly with the use of intentional mentions. +Setting `"notifications":{"room":X}` allows to choose `X` for the power required +level to ring the whole room. + ## Unstable prefix While this MSC is not present in the spec, clients and widgets should: -- Use `org.matrix.msc4075.` in place of `m.` in all new identifiers of this MSC. +- Use `org.matrix.msc4075.` in place of `m.` in all new identifiers of this MSC. (`m.call.notify`) ## Dependencies From a00113eda18d9eb21ce9d1cb6a5f8db9b2ea03a8 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 19 Feb 2024 09:29:31 +0100 Subject: [PATCH 06/12] review fixes Signed-off-by: Timo K --- proposals/4075-call-notify-event.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 192d91e76dd..cb09321c9e3 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -19,7 +19,7 @@ mentions make sure no unnecessary push notification is sent. This event contains the following fields by leveraging intentional mentions. -``` +```json { "content": { "application": "m.call | m.other_matrix_session_type | ...", @@ -94,8 +94,7 @@ Sending a `m.call.notify` should happen only if all of these conditions apply: It would be possible to use the call member room state events to determine a call start. The logic would be as following: - -_If we receive an event we check if there is are already other members +_If we receive an event we check if are already other members (call.member events) for the call. In case there is not we make the phone ring._ Pros: @@ -105,10 +104,7 @@ Pros: start a new call. Because they would automatically send an event by joining. - There would be less traffic. With the proposed solution the first one who joins needs to send a `m.call.notify` event and a `m.call.member` state event. -- Very flexible, since the `m.call.notify` event is separate from a call - participation. This allows an external instance (a meeting organizer bot) to - just ring all the users which are invited to a meeting without needing to be - part of the call. + Cons @@ -117,6 +113,11 @@ Cons (Consider a very large room where I want to start a call only for the interested ones who want to discuss a side project. It would be very annoying if the initiator could not control how and who is going to be informed about that call.) + +- Additionally, it is not as flexible as the proposed separate event. + Which allows an external instance (a meeting organizer bot) to + just ring all the users which are invited to a meeting without needing to + participate in the call with a `m.call.member` event of the call. - Push notifications would need to be sent for EVERY `m.call.member` state event update. For each joining and leaving user and for each membership update during a call (due to a SFU (single forwarding unit) change, changing devices From a57720b3b887214e84c94359aa75bdbb49db8eb5 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 13 May 2024 14:15:45 +0200 Subject: [PATCH 07/12] add Limitations and recommendations Signed-off-by: Timo K --- proposals/4075-call-notify-event.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index cb09321c9e3..75c431ec8af 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -90,9 +90,33 @@ Sending a `m.call.notify` should happen only if all of these conditions apply: participate but the other condition applies. (So the obvious case is, that this is the first user in a new call session). +### Limitations and recommendations + +- Encrypted rooms configured as `mentions only` are currently not sending push + notifications for encrypted events. Hence the client would not ring even though + the ring event contains `m.mentions`. + - As a stop gat, it is recommended, that the client sends unencrypted `m.call.notify` + events in such rooms. + - As soon as [MSC3996: Encrypted mentions-only rooms](https://github.com/matrix-org/matrix-spec-proposals/pull/3996) + is supported `m.has_mentions` should be used instead of unencrypted call + notify events. +- Wanting to ring a user who you do not have a shared room with is not possible. + It might be an undesired capability that your device can be started to ring + by users you have not yet interacted on matrix. + On the other hand this might be desired to mimic what ppl expect from using + the telephone network. + Entering a matrix userId allows to call someone (Ring their phone). + (It would be possible to disable/configure this on the receiving + device) + - The location to put this information would be the invite event. + This would be an edge case and only required for the specific usecase + of being able to ring without a shared DM/Room. + It should be discussed in an additional MSC and is not part of this proposal. + ## Alternatives -It would be possible to use the call member room state events to determine a call start. +It would be possible to use the call member room state events to determine a call +start. The logic would be as following: _If we receive an event we check if are already other members (call.member events) for the call. In case there is not we make the phone ring._ @@ -105,7 +129,6 @@ Pros: - There would be less traffic. With the proposed solution the first one who joins needs to send a `m.call.notify` event and a `m.call.member` state event. - Cons - All the ringing conditions run on the receiving user. There is no way for the @@ -131,7 +154,7 @@ Cons ### Explicitly unspecified conditions -- The duration of the ring sound is a deliberately chosen +- The duration of the ring sound is deliberately chosen to be a clients decision. - The ring sound is a client choice as well. (It was considered to add the ring sound to the notify event but how "ringing" actually should From b7febd1952f5b80e9152b10963c5d0ec2af3d566 Mon Sep 17 00:00:00 2001 From: Timo Date: Wed, 10 Jul 2024 09:18:25 +0200 Subject: [PATCH 08/12] fixes --- proposals/4075-call-notify-event.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 75c431ec8af..74740dfe339 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -35,7 +35,7 @@ This event contains the following fields by leveraging intentional mentions. } ``` -In the following we define **call** as any matrix RTC session with the +In the following we define **call** as any MatrixRTC session with the same `"application"` and the same application specific data. In the case of `"m.call"`, the same `"call_id"`. @@ -74,7 +74,7 @@ Ringing (or notifying) should happen only if all these conditions apply:\ - If a notify event is received in "real time":\ Notify events that are older then **10 seconds** are ignored (using the local timestamp computed via `unsigned.age`).\ - Otherwise a clients syncing for the first time would ring for outdated call events. + Otherwise a client syncing for the first time would ring for outdated call events. In general ringing only makes sense in "real time". A 10 second syncing latency is allowed. Any client which is not able to receive the event in this period should not ring to prohibit (annoying/misleading/irrelevant) outdated rings. From 109af479a975bb259194b9fd5d971ac5a5f6123f Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 8 Oct 2024 18:01:09 +0200 Subject: [PATCH 09/12] Add extensible event fallback --- proposals/4075-call-notify-event.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index 74740dfe339..e722c45b85b 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -17,7 +17,7 @@ wants to start a call. This event is added to the push rules for clients which support calling so they get push notifications. The push rules for intentional mentions make sure no unnecessary push notification is sent. -This event contains the following fields by leveraging intentional mentions. +This event contains the following fields including intentional mentions and extensible events. ```json { @@ -31,7 +31,10 @@ This event contains the following fields by leveraging intentional mentions. // for application = "m.call": "call_id": "some_id", - } + // Extensible events fallback + "m.text": "<@room|@user1, @user2 and @user3> + Join the call in this room with a supported client." + } } ``` @@ -39,9 +42,11 @@ In the following we define **call** as any MatrixRTC session with the same `"application"` and the same application specific data. In the case of `"m.call"`, the same `"call_id"`. -On retrieval, the event should not be rendered in the timeline. -But if the notify conditions (listed below) apply, -the client has to inform the user about the **call** with an appropriate user flow. +If it does support the event it should not be rendered in the timeline. +(Call timeline elements are done using the `m.call.member` state events.) + +But, if the notify conditions (listed below) apply, +the client has to inform the user about the **call** with an appropriate user experience. For `notify_by == "ring"` some kind of sound is required (except if overwritten by another client specific setting), for `notify_by == "notification"` a visual indication is enough. @@ -90,6 +95,13 @@ Sending a `m.call.notify` should happen only if all of these conditions apply: participate but the other condition applies. (So the obvious case is, that this is the first user in a new call session). +### Fallback with extensible events + +If clients do not support `m.call.notify` events, they will however draw the extensible event fallback. +The exact content is up the the sending client and can contain more detailed instructions on how to get +access to a supporting client. It has to include the `@room` or the mentioned user list and has +to communicate the message that those users are invited to participate in a call. + ### Limitations and recommendations - Encrypted rooms configured as `mentions only` are currently not sending push From 655bcb3770e3f2ffe60f4780e4818a76aef4e837 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 25 Nov 2024 08:23:33 +0000 Subject: [PATCH 10/12] make ugly json highlighting errors go away --- proposals/4075-call-notify-event.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index e722c45b85b..a96f4e045f5 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -19,7 +19,7 @@ mentions make sure no unnecessary push notification is sent. This event contains the following fields including intentional mentions and extensible events. -```json +```json5 { "content": { "application": "m.call | m.other_matrix_session_type | ...", From 545931d5488e8fedabeaeb50c58292f18a33e43b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 25 Nov 2024 08:36:17 +0000 Subject: [PATCH 11/12] readability fixes --- proposals/4075-call-notify-event.md | 40 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index a96f4e045f5..dc73df101f2 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -6,8 +6,8 @@ This is of interest in 1:1 Rooms/Calls but also in bigger rooms ringing can be d Legacy calls are using room events to negotiate the call. A client could use the initial steps in the negotiation to also make the phone ring. -With matrix RTC based calls this signalling is done over state events. -Also matrix RTC enables large group calls which makes it very +With MatrixRTC based calls this signalling is done over state events. +Also MatrixRTC enables large group calls which makes it very desirable to have more configurations over the ringing process. ## Proposal @@ -21,6 +21,7 @@ This event contains the following fields including intentional mentions and exte ```json5 { + "type": "m.call.notify", "content": { "application": "m.call | m.other_matrix_session_type | ...", "m.mentions": {"user_ids": [], "room": true | false}, @@ -54,7 +55,7 @@ This visual indication should be more than an unread indicator and similar to a notification banner. This is not enforced by the spec however and ultimately a client choice. -Ringing (or notifying) should happen only if all these conditions apply:\ +Ringing (or notifying) should happen only if all these conditions apply: - `m.call.notify` content:\ If the user is not part of the `m.mentions` section as defined in @@ -107,44 +108,45 @@ to communicate the message that those users are invited to participate in a call - Encrypted rooms configured as `mentions only` are currently not sending push notifications for encrypted events. Hence the client would not ring even though the ring event contains `m.mentions`. - - As a stop gat, it is recommended, that the client sends unencrypted `m.call.notify` + - As a stop gap, it is recommended, that the client sends unencrypted `m.call.notify` events in such rooms. - As soon as [MSC3996: Encrypted mentions-only rooms](https://github.com/matrix-org/matrix-spec-proposals/pull/3996) is supported `m.has_mentions` should be used instead of unencrypted call notify events. -- Wanting to ring a user who you do not have a shared room with is not possible. +- Ringing a user who you do not have a shared room with is not supported + by this MSC. It might be an undesired capability that your device can be started to ring by users you have not yet interacted on matrix. - On the other hand this might be desired to mimic what ppl expect from using + On the other hand this might be desired to mimic what people expect from using the telephone network. - Entering a matrix userId allows to call someone (Ring their phone). - (It would be possible to disable/configure this on the receiving + (It should be possible to disable/configure this on the receiving device) - The location to put this information would be the invite event. - This would be an edge case and only required for the specific usecase + This would be an edge case and only required for the specific use case of being able to ring without a shared DM/Room. It should be discussed in an additional MSC and is not part of this proposal. ## Alternatives -It would be possible to use the call member room state events to determine a call +It could be possible to use the call member room state events to determine a call start. The logic would be as following: -_If we receive an event we check if are already other members +_If we receive an event we check if there are already other members (call.member events) for the call. In case there is not we make the phone ring._ Pros: - This would not require any new event. -- The clients can not "forget" to ring the others about the when they - start a new call. Because they would automatically send an event by joining. -- There would be less traffic. With the proposed solution the first one who joins - needs to send a `m.call.notify` event and a `m.call.member` state event. +- The clients can not "forget" to ring the others when they + start a new call, because they would automatically send an event by joining. +- There would be less traffic. With the proposed solution in this MSC, the first + client who joins needs to send a `m.call.notify` event and a `m.call.member` + state event. Cons - All the ringing conditions run on the receiving user. There is no way for the - user who start the call to decide if it should ring the other participants. + user who starts the call to decide if it should ring the other participants. (Consider a very large room where I want to start a call only for the interested ones who want to discuss a side project. It would be very annoying if the initiator could not control how and who is going to be informed about that call.) @@ -176,9 +178,9 @@ Cons ## Security considerations This is another timeline event where any room participant can send a push -notification to others. Since this will make clients ring this has a higher -effect on the receiver. Since ringing has to obey the mute settings, it is -very easy for the targeted users to mitigate the "attack". It can be very +notification to others. Since this will make clients ring this has a high +impact on the receiver. However, since ringing has to obey the mute settings, it is +very easy for the targeted users to mitigate unwanted ringing. It can be very much compared to spamming a room with "@room" messages. The default power level for `m.call.notify` is `50` and equivalent to the default From 04635ebc908e8299c77c0abe7c025cab393a6eed Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 17 Dec 2024 07:26:11 +0000 Subject: [PATCH 12/12] Latest --- proposals/4075-call-notify-event.md | 151 ++++++++++++++-------------- 1 file changed, 77 insertions(+), 74 deletions(-) diff --git a/proposals/4075-call-notify-event.md b/proposals/4075-call-notify-event.md index dc73df101f2..0b5ad1db403 100644 --- a/proposals/4075-call-notify-event.md +++ b/proposals/4075-call-notify-event.md @@ -1,80 +1,89 @@ -# MSC4075: MatrixRTC Call Ringing +# MSC4075: MatrixRTC Ringing -It is important that a call initiated on clientA can make targeted clients ring. +It is important that an RTC session initiated on clientA can make targeted clients ring. This is of interest in 1:1 Rooms/Calls but also in bigger rooms ringing can be desired. -Legacy calls are using room events to negotiate the call. -A client could use the initial steps in the negotiation to also make the phone ring. +The existing "legacy" [1:1 VoIP calling in Matrix](https://spec.matrix.org/v1.11/client-server-api/#voice-over-ip) +uses room events to negotiate the call. +A client can use the initial steps in the negotiation to also make the phone ring. -With MatrixRTC based calls this signalling is done over state events. -Also MatrixRTC enables large group calls which makes it very +With [MSC4143: MatrixRTC](https://github.com/matrix-org/matrix-spec-proposals/pull/4143) +this signalling is done over state events. Furthermore, [MatrixRTC](https://github.com/matrix-org/matrix-spec-proposals/pull/4143) +allows for large group calls (not just 1:1) which makes it very desirable to have more configurations over the ringing process. ## Proposal -A new event `m.call.notify` is proposed which can be sent by a client that -wants to start a call. This event is added to the push rules for clients which -support calling so they get push notifications. The push rules for intentional +A new event `m.rtc.notify` is proposed which can be sent by a client that +wants to notify others about the existence of an session for an MatrixRTC application. +This event is added to the push rules for clients which +support the application type so they receive push notifications. The push rules for intentional mentions make sure no unnecessary push notification is sent. -This event contains the following fields including intentional mentions and extensible events. +This event contains the following fields by leveraging intentional mentions. ```json5 { - "type": "m.call.notify", "content": { - "application": "m.call | m.other_matrix_session_type | ...", "m.mentions": {"user_ids": [], "room": true | false}, "notify_type": "ring | notification", + "session": { + // session content from the corresponding m.rtc.member event + "application": "m.call | m.other_matrix_session_type | ...", + }, // Application specific data, // optional fields to disambiguate which session // this notify event belongs to: - - // for application = "m.call": - "call_id": "some_id", - // Extensible events fallback - "m.text": "<@room|@user1, @user2 and @user3> - Join the call in this room with a supported client." - } + } } ``` +The fields are defined as follows: + +- `m.mentions` optional:\ + Has the structure as defined for `m.mentions` in the [Client-Server API](https://spec.matrix.org/v1.11/client-server-api/#definition-mmentions). +- `notify_type` required string:\ + The type of notification to send.\ + `ring`: The client should ring.\ + `notification`: The client should show a notification. +- `session` required object: the `session` content from the corresponding `m.rtc.member` event. + In the following we define **call** as any MatrixRTC session with the -same `"application"` and the same application specific data. -In the case of `"m.call"`, the same `"call_id"`. +same `"session"` contents. -If it does support the event it should not be rendered in the timeline. -(Call timeline elements are done using the `m.call.member` state events.) +### Client behaviour on receiving a `m.rtc.notify` event -But, if the notify conditions (listed below) apply, -the client has to inform the user about the **call** with an appropriate user experience. -For `notify_by == "ring"` some kind of sound is required +On retrieval, the client should not render the event in the timeline. +If the notify conditions (listed below) apply, +the client has to inform the user about the **call** with an appropriate user flow. +For `notify_type == "ring"` some kind of sound is required (except if overwritten by another client specific setting), -for `notify_by == "notification"` a visual indication is enough. +for `notify_type == "notification"` a visual indication is enough. This visual indication should be more than an unread indicator and similar to a notification banner. This is not enforced by the spec however and ultimately a client choice. -Ringing (or notifying) should happen only if all these conditions apply: +The client should only inform the user if all of the following conditions apply: -- `m.call.notify` content:\ - If the user is not part of the `m.mentions` section as defined in - [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) - this event can be ignored. (Push notifications are automatically filtered +- `m.rtc.notify` content:\ + If the user is *not* listed in the `m.mentions` section as defined in the\ + [Client-Server API](https://spec.matrix.org/v1.11/client-server-api/#definition-mmentions),\ + the event should be ignored. (Push notifications are automatically filtered so this only is important for events received via a sync) - Local notification settings:\ - If the room is set to silent, it will never play a ring sound. A `m.call.notify` - event will at most be used to mark the room as unread or update the rooms + If the room is set to silent, the client should never play a ring sound. + In this scenario, a `m.rtc.notify` + event should at most be used to mark the room as unread or update the rooms "has active **call** icon". (the exact behavior is up to the client) - Currently playing a ring sound (room timeline):\ If the user already received a ring event for this **call** and is playing - the ring sound any incoming `m.call.notify` for the same **call** - should be ignored. If the user failed to pick up and a new `m.call.notify` + the ring sound any incoming `m.rtc.notify` for the same **call** + should be ignored. If the user failed to pick up and a new `m.rtc.notify` arrives for the same room the device should ring again. - Current user is a member of the the **call** (room state):\ - None of the devices should ring if they receive a `m.call.notify` if the - rooms state `m.call.member` event of the user contains a membership for - the **call** in the `m.call.notify` event. + None of the devices should ring if they receive a `m.rtc.notify` if the + rooms state `m.rtc.member` event of the user contains a membership for + the **call** in the `m.rtc.notify` event. This includes stopping the current ring sound if the room state updates so this condition is true. - If a notify event is received in "real time":\ @@ -85,77 +94,72 @@ Ringing (or notifying) should happen only if all these conditions apply: is allowed. Any client which is not able to receive the event in this period should not ring to prohibit (annoying/misleading/irrelevant) outdated rings. -Sending a `m.call.notify` should happen only if all of these conditions apply: +### Client behaviour when sending a `m.rtc.notify` event + +Sending a `m.rtc.notify` should happen only if all of these conditions apply: - If the user deliberately wants to send a new notify event - (It is possible to send a `m.call.notify` for an ongoing call if that + (It is possible to send a `m.rtc.notify` for an ongoing call if that makes sense. Starting a call ahead of time, planning in a small group, ringing another set of users at a specific time so they don't forget to join. Ringing one specific user again who missed joining during the first ring.) -- If the user has not yet received a `m.call.notify` for the **call** they want to +- If the user has not yet received a `m.rtc.notify` for the **call** they want to participate but the other condition applies. (So the obvious case is, that this is the first user in a new call session). -### Fallback with extensible events - -If clients do not support `m.call.notify` events, they will however draw the extensible event fallback. -The exact content is up the the sending client and can contain more detailed instructions on how to get -access to a supporting client. It has to include the `@room` or the mentioned user list and has -to communicate the message that those users are invited to participate in a call. - ### Limitations and recommendations - Encrypted rooms configured as `mentions only` are currently not sending push notifications for encrypted events. Hence the client would not ring even though the ring event contains `m.mentions`. - - As a stop gap, it is recommended, that the client sends unencrypted `m.call.notify` + - As a stop gat, it is recommended, that the client sends unencrypted `m.rtc.notify` events in such rooms. - As soon as [MSC3996: Encrypted mentions-only rooms](https://github.com/matrix-org/matrix-spec-proposals/pull/3996) is supported `m.has_mentions` should be used instead of unencrypted call notify events. -- Ringing a user who you do not have a shared room with is not supported - by this MSC. +- Wanting to ring a user who you do not have a shared room with is not possible. It might be an undesired capability that your device can be started to ring by users you have not yet interacted on matrix. - On the other hand this might be desired to mimic what people expect from using + On the other hand this might be desired to mimic what ppl expect from using the telephone network. - (It should be possible to disable/configure this on the receiving + Entering a matrix userId allows to call someone (Ring their phone). + (It would be possible to disable/configure this on the receiving device) - The location to put this information would be the invite event. - This would be an edge case and only required for the specific use case + This would be an edge case and only required for the specific usecase of being able to ring without a shared DM/Room. It should be discussed in an additional MSC and is not part of this proposal. ## Alternatives -It could be possible to use the call member room state events to determine a call +### Use call member room state events + +It would be possible to use the call member room state events to determine a call start. The logic would be as following: -_If we receive an event we check if there are already other members +_If we receive an event we check if are already other members (call.member events) for the call. In case there is not we make the phone ring._ Pros: - This would not require any new event. -- The clients can not "forget" to ring the others when they - start a new call, because they would automatically send an event by joining. -- There would be less traffic. With the proposed solution in this MSC, the first - client who joins needs to send a `m.call.notify` event and a `m.call.member` - state event. +- The clients can not "forget" to ring the others about the when they + start a new call. Because they would automatically send an event by joining. +- There would be less traffic. With the proposed solution the first one who joins + needs to send a `m.rtc.notify` event and a `m.rtc.member` state event. Cons - All the ringing conditions run on the receiving user. There is no way for the - user who starts the call to decide if it should ring the other participants. + user who start the call to decide if it should ring the other participants. (Consider a very large room where I want to start a call only for the interested ones who want to discuss a side project. It would be very annoying if the initiator could not control how and who is going to be informed about that call.) - - Additionally, it is not as flexible as the proposed separate event. Which allows an external instance (a meeting organizer bot) to just ring all the users which are invited to a meeting without needing to - participate in the call with a `m.call.member` event of the call. -- Push notifications would need to be sent for EVERY `m.call.member` state event + participate in the call with a `m.rtc.member` event of the call. +- Push notifications would need to be sent for EVERY `m.rtc.member` state event update. For each joining and leaving user and for each membership update during a call (due to a SFU (single forwarding unit) change, changing devices (could even happen for screen shares if the screen share is implemented as a @@ -178,13 +182,13 @@ Cons ## Security considerations This is another timeline event where any room participant can send a push -notification to others. Since this will make clients ring this has a high -impact on the receiver. However, since ringing has to obey the mute settings, it is -very easy for the targeted users to mitigate unwanted ringing. It can be very +notification to others. Since this will make clients ring this has a higher +effect on the receiver. Since ringing has to obey the mute settings, it is +very easy for the targeted users to mitigate the "attack". It can be very much compared to spamming a room with "@room" messages. -The default power level for `m.call.notify` is `50` and equivalent to the default -power level required for `m.call.member` state events. +The default power level for `m.rtc.notify` is `50` and equivalent to the default +power level required for `m.rtc.member` state events. Additional control is provided indirectly with the use of intentional mentions. Setting `"notifications":{"room":X}` allows to choose `X` for the power required @@ -194,9 +198,8 @@ level to ring the whole room. While this MSC is not present in the spec, clients and widgets should: -- Use `org.matrix.msc4075.` in place of `m.` in all new identifiers of this MSC. -(`m.call.notify`) +- Use `org.matrix.msc4075.call.notify` in place of `m.rtc.notify` as the event type ## Dependencies -This MSC builds on Intentional Mentions [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952). +This MSC builds on [MSC4143: MatrixRTC](https://github.com/matrix-org/matrix-spec-proposals/pull/4143).