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).