mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-08-05 07:27:52 +02:00
Compare commits
No commits in common. "656bf61a3cb1a1c5cb5358ad378de16c03354980" and "59b92ce9e6c57fcbfc488cbad992a9324599c475" have entirely different histories.
656bf61a3c
...
59b92ce9e6
6
.github/_typos.toml
vendored
6
.github/_typos.toml
vendored
|
|
@ -3,12 +3,6 @@ extend-exclude = ["/themes", "/attic", "/data-definitions", "*.css", "syntax.scs
|
||||||
|
|
||||||
[default]
|
[default]
|
||||||
check-filename = true
|
check-filename = true
|
||||||
extend-ignore-re = [
|
|
||||||
# Ignore lines that start with `# Copyright ` (i.e. comments containing a
|
|
||||||
# copyright statement in YAML files), they may contain a first or last name
|
|
||||||
# that can be wrongfully detected as typos.
|
|
||||||
"(?Rm)^#\\s*Copyright\\s.*$",
|
|
||||||
]
|
|
||||||
|
|
||||||
[default.extend-identifiers]
|
[default.extend-identifiers]
|
||||||
au1ba7o = "au1ba7o"
|
au1ba7o = "au1ba7o"
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify formats of string types.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify formats of string types.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify formats of string types.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Ignore typos in copyright statements.
|
|
||||||
|
|
@ -90,11 +90,11 @@ room that the event was sent to or dismissing a notification in order
|
||||||
for the event to count as "read". Clients SHOULD NOT send read receipts
|
for the event to count as "read". Clients SHOULD NOT send read receipts
|
||||||
for events sent by their own user.
|
for events sent by their own user.
|
||||||
|
|
||||||
Similar to the rules for sending receipts, [threaded receipts](#threaded-read-receipts)
|
Similar to the rules for sending receipts, threaded receipts should appear
|
||||||
should appear in the context of the thread. If a thread is rendered behind a
|
in the context of the thread. If a thread is rendered behind a disclosure,
|
||||||
disclosure, the client hasn't yet shown the event (or any applicable read
|
the client hasn't yet shown the event (or any applicable read receipts)
|
||||||
receipts) to the user. Once they expand the thread though, a threaded read
|
to the user. Once they expand the thread though, a threaded read receipt
|
||||||
receipt would be sent and per-thread receipts from other users shown.
|
would be sent and per-thread receipts from other users shown.
|
||||||
|
|
||||||
A client can update the markers for its user by interacting with the
|
A client can update the markers for its user by interacting with the
|
||||||
following HTTP APIs.
|
following HTTP APIs.
|
||||||
|
|
@ -232,5 +232,5 @@ MUST NOT appear in this federated `m.receipt` EDU.
|
||||||
|
|
||||||
#### Security considerations
|
#### Security considerations
|
||||||
|
|
||||||
As receipts are sent outside the context of the [event graph](/#event-graphs),
|
As receipts are sent outside the context of the event graph, there are
|
||||||
there are no integrity checks performed on the contents of `m.receipt` events.
|
no integrity checks performed on the contents of `m.receipt` events.
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
|
|
||||||
### Voice over IP
|
### Voice over IP
|
||||||
|
|
||||||
This module outlines how two users in a room can set up a Voice over IP (VoIP)
|
This module outlines how two users in a room can set up a Voice over IP
|
||||||
call to each other. Voice and video calls are built upon the [WebRTC 1.0
|
(VoIP) call to each other. Voice and video calls are built upon the
|
||||||
standard](https://www.w3.org/TR/webrtc/). Call signalling is achieved by sending
|
WebRTC 1.0 standard. Call signalling is achieved by sending [message
|
||||||
[message events](#events) to the room. In this version of the spec, only
|
events](#events) to the room. In this version of the spec, only two-party
|
||||||
two-party communication is supported (e.g. between two peers, or between a peer
|
communication is supported (e.g. between two peers, or between a peer
|
||||||
and a multi-point conferencing unit). Calls can take place in rooms with
|
and a multi-point conferencing unit). Calls can take place in rooms with
|
||||||
multiple members, but only two devices can take part in the call.
|
multiple members, but only two devices can take part in the call.
|
||||||
|
|
||||||
All VoIP events have a `version` field. This is used to determine whether
|
All VoIP events have a `version` field. This is used to determine whether
|
||||||
devices support this new version of the protocol. For example, clients can use
|
devices support this new version of the protocol. For example, clients can use
|
||||||
this field to know whether to expect an [`m.call.select_answer`](#mcallselect_answer)
|
this field to know whether to expect an `m.call.select_answer` event from their
|
||||||
event from their opponent. If clients see events with `version` other than `0`
|
opponent. If clients see events with `version` other than `0` or `"1"`
|
||||||
or `"1"` (including, for example, the numeric value `1`), they should treat
|
(including, for example, the numeric value `1`), they should treat these the
|
||||||
these the same as if they had `version` == `"1"`.
|
same as if they had `version` == `"1"`.
|
||||||
|
|
||||||
Note that this implies any and all future versions of VoIP events should be
|
Note that this implies any and all future versions of VoIP events should be
|
||||||
backwards-compatible. If it does become necessary to introduce a non
|
backwards-compatible. If it does become necessary to introduce a non
|
||||||
|
|
@ -29,10 +29,10 @@ lowercase alphanumeric characters is recommended. Parties in the call are identi
|
||||||
`(user_id, party_id)`.
|
`(user_id, party_id)`.
|
||||||
|
|
||||||
The client adds a `party_id` field containing this ID to the top-level of the content of all VoIP events
|
The client adds a `party_id` field containing this ID to the top-level of the content of all VoIP events
|
||||||
it sends on the call, including [`m.call.invite`](#mcallinvite). Clients use this to identify remote echo
|
it sends on the call, including `m.call.invite`. Clients use this to identify remote echo of their own
|
||||||
of their own events: since a user may call themselves, they cannot simply ignore events from their own
|
events: since a user may call themselves, they cannot simply ignore events from their own user. This
|
||||||
user. This field also identifies different answers sent by different clients to an invite, and matches
|
field also identifies different answers sent by different clients to an invite, and matches `m.call.candidates`
|
||||||
[`m.call.candidates`](#mcallcandidates) events to their respective answer/invite.
|
events to their respective answer/invite.
|
||||||
|
|
||||||
A client implementation may choose to use the device ID used in end-to-end cryptography for this purpose,
|
A client implementation may choose to use the device ID used in end-to-end cryptography for this purpose,
|
||||||
or it may choose, for example, to use a different one for each call to avoid leaking information on which
|
or it may choose, for example, to use a different one for each call to avoid leaking information on which
|
||||||
|
|
@ -44,16 +44,15 @@ A grammar for `party_id` is defined [below](#grammar-for-voip-ids).
|
||||||
#### Politeness
|
#### Politeness
|
||||||
In line with [WebRTC perfect negotiation](https://w3c.github.io/webrtc-pc/#perfect-negotiation-example)
|
In line with [WebRTC perfect negotiation](https://w3c.github.io/webrtc-pc/#perfect-negotiation-example)
|
||||||
there are rules to establish which party is polite in the process of renegotiation. The callee is
|
there are rules to establish which party is polite in the process of renegotiation. The callee is
|
||||||
always the polite party. In a [glare](#glare) situation, the politeness of a party is therefore
|
always the polite party. In a glare situation, the politeness of a party is therefore determined by
|
||||||
determined by whether the inbound or outbound call is used: if a client discards its outbound call
|
whether the inbound or outbound call is used: if a client discards its outbound call in favour of
|
||||||
in favour of an inbound call, it becomes the polite party.
|
an inbound call, it becomes the polite party.
|
||||||
|
|
||||||
#### Call Event Liveness
|
#### Call Event Liveness
|
||||||
[`m.call.invite`](#mcallinvite) contains a `lifetime` field that indicates how long the offer is
|
`m.call.invite` contains a `lifetime` field that indicates how long the offer is valid for. When
|
||||||
valid for. When a client receives an invite, it should use the event's `age` field in the
|
a client receives an invite, it should use the event's `age` field in the sync response plus the
|
||||||
[`GET /sync`](#get_matrixclientv3sync) response plus the time since it received the event from the
|
time since it received the event from the homeserver to determine whether the invite is still valid.
|
||||||
homeserver to determine whether the invite is still valid. The use of the `age` field ensures that
|
The use of the `age` field ensures that incorrect clocks on client devices don't break calls.
|
||||||
incorrect clocks on client devices don't break calls.
|
|
||||||
|
|
||||||
If the invite is still valid *and will remain valid for long enough for the user to accept the call*,
|
If the invite is still valid *and will remain valid for long enough for the user to accept the call*,
|
||||||
it should signal an incoming call. The amount of time allowed for the user to accept the call may
|
it should signal an incoming call. The amount of time allowed for the user to accept the call may
|
||||||
|
|
@ -84,7 +83,7 @@ Clients should aim to send a small number of candidate events, with guidelines:
|
||||||
|
|
||||||
#### End-of-candidates
|
#### End-of-candidates
|
||||||
An ICE candidate whose value is the empty string means that no more ICE candidates will
|
An ICE candidate whose value is the empty string means that no more ICE candidates will
|
||||||
be sent. Clients must send such a candidate in an [`m.call.candidates`](#mcallcandidates) message.
|
be sent. Clients must send such a candidate in an `m.call.candidates` message.
|
||||||
The WebRTC spec requires browsers to generate such a candidate, however note that at time of writing,
|
The WebRTC spec requires browsers to generate such a candidate, however note that at time of writing,
|
||||||
not all browsers do (Chrome does not, but does generate an `icegatheringstatechange` event). The
|
not all browsers do (Chrome does not, but does generate an `icegatheringstatechange` event). The
|
||||||
client should send any remaining candidates once candidate generation finishes, ignoring timeouts above.
|
client should send any remaining candidates once candidate generation finishes, ignoring timeouts above.
|
||||||
|
|
@ -131,48 +130,36 @@ or not there have been any changes to the Matrix spec.
|
||||||
A call is set up with message events exchanged as follows:
|
A call is set up with message events exchanged as follows:
|
||||||
|
|
||||||
```nohighlight
|
```nohighlight
|
||||||
+---------+ +---------+
|
Caller Callee
|
||||||
| Caller | | Callee |
|
[Place Call]
|
||||||
+---------+ +---------+
|
m.call.invite ----------->
|
||||||
| |
|
m.call.candidate -------->
|
||||||
(Places Call) |
|
[..candidates..] -------->
|
||||||
|------- m.call.invite ------->|
|
[Answers call]
|
||||||
|----- m.call.candidate ------>|
|
<--------------- m.call.answer
|
||||||
|----- [..candidates..] ------>|
|
m.call.select_answer ----------->
|
||||||
| |
|
[Call is active and ongoing]
|
||||||
| (Answers call)
|
<--------------- m.call.hangup
|
||||||
|<------ m.call.answer --------|
|
|
||||||
|--- m.call.select_answer --->|
|
|
||||||
. .
|
|
||||||
. (Call is active and ongoing) .
|
|
||||||
. .
|
|
||||||
| (Ends call)
|
|
||||||
|<------ m.call.hangup --------|
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or a rejected call:
|
Or a rejected call:
|
||||||
|
|
||||||
```nohighlight
|
```nohighlight
|
||||||
+---------+ +---------+
|
Caller Callee
|
||||||
| Caller | | Callee |
|
m.call.invite ------------>
|
||||||
+---------+ +---------+
|
m.call.candidate --------->
|
||||||
| |
|
[..candidates..] --------->
|
||||||
(Places Call) |
|
[Rejects call]
|
||||||
|------- m.call.invite ------->|
|
<-------------- m.call.hangup
|
||||||
|----- m.call.candidate ------>|
|
|
||||||
|----- [..candidates..] ------>|
|
|
||||||
| |
|
|
||||||
| (Rejects call)
|
|
||||||
|<------ m.call.reject --------|
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Calls are negotiated according to the WebRTC specification.
|
Calls are negotiated according to the WebRTC specification.
|
||||||
|
|
||||||
In response to an incoming invite, a client may do one of several things:
|
In response to an incoming invite, a client may do one of several things:
|
||||||
* Attempt to accept the call by sending an [`m.call.answer`](#mcallanswer).
|
* Attempt to accept the call by sending an `m.call.answer`.
|
||||||
* Actively reject the call everywhere: send an [`m.call.reject`](#mcallreject) as per above, which
|
* Actively reject the call everywhere: send an `m.call.reject` as per above, which will stop the call from
|
||||||
will stop the call from ringing on all the user's devices and the caller's client will inform
|
ringing on all the user's devices and the caller's client will inform them that the user has
|
||||||
them that the user has rejected their call.
|
rejected their call.
|
||||||
* Ignore the call: send no events, but stop alerting the user about the call. The user's other
|
* Ignore the call: send no events, but stop alerting the user about the call. The user's other
|
||||||
devices will continue to ring, and the caller's device will continue to indicate that the call
|
devices will continue to ring, and the caller's device will continue to indicate that the call
|
||||||
is ringing, and will time the call out in the normal way if no other device responds.
|
is ringing, and will time the call out in the normal way if no other device responds.
|
||||||
|
|
@ -237,8 +224,8 @@ As calls are "placed" to rooms rather than users, the glare resolution
|
||||||
algorithm outlined below is only considered for calls which are to the
|
algorithm outlined below is only considered for calls which are to the
|
||||||
same room. The algorithm is as follows:
|
same room. The algorithm is as follows:
|
||||||
|
|
||||||
- If an [`m.call.invite`](#mcallinvite) to a room is received whilst the
|
- If an `m.call.invite` to a room is received whilst the client is
|
||||||
client is **preparing to send** an `m.call.invite` to the same room:
|
**preparing to send** an `m.call.invite` to the same room:
|
||||||
- the client should cancel its outgoing call and instead
|
- the client should cancel its outgoing call and instead
|
||||||
automatically accept the incoming call on behalf of the user.
|
automatically accept the incoming call on behalf of the user.
|
||||||
- If an `m.call.invite` to a room is received **after the client has
|
- If an `m.call.invite` to a room is received **after the client has
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ paths:
|
||||||
example: "!wefuh21ffskfuh345:example.com"
|
example: "!wefuh21ffskfuh345:example.com"
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: mx-room-id
|
|
||||||
pattern: "^!"
|
|
||||||
- in: path
|
- in: path
|
||||||
name: receiptType
|
name: receiptType
|
||||||
description: |-
|
description: |-
|
||||||
|
|
@ -64,8 +62,6 @@ paths:
|
||||||
example: $1924376522eioj:example.com
|
example: $1924376522eioj:example.com
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: mx-event-id
|
|
||||||
pattern: "^\\$"
|
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
|
@ -76,8 +72,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
x-addedInMatrixVersion: "1.4"
|
x-addedInMatrixVersion: "1.4"
|
||||||
description: |-
|
description: |-
|
||||||
The [thread root](/client-server-api/#threading)'s
|
The root thread event's ID (or `main`) for which
|
||||||
[event ID](/appendices#event-ids) (or `main`) for which
|
|
||||||
thread this receipt is intended to be under. If
|
thread this receipt is intended to be under. If
|
||||||
not specified, the read receipt is *unthreaded*
|
not specified, the read receipt is *unthreaded*
|
||||||
(default).
|
(default).
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,6 @@ paths:
|
||||||
example: "@alice:example.com"
|
example: "@alice:example.com"
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: mx-user-id
|
|
||||||
pattern: "^@"
|
|
||||||
- in: path
|
- in: path
|
||||||
name: roomId
|
name: roomId
|
||||||
description: The room in which the user is typing.
|
description: The room in which the user is typing.
|
||||||
|
|
@ -45,8 +43,6 @@ paths:
|
||||||
example: "!wefh3sfukhs:example.com"
|
example: "!wefh3sfukhs:example.com"
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: mx-room-id
|
|
||||||
pattern: "^!"
|
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,6 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
|
||||||
pattern: "^turns?:"
|
|
||||||
description: A list of TURN URIs
|
description: A list of TURN URIs
|
||||||
ttl:
|
ttl:
|
||||||
type: integer
|
type: integer
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,44 @@
|
||||||
$schema: https://json-schema.org/draft/2020-12/schema
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
type: object
|
"type": "object",
|
||||||
description: This event is sent by the callee when they wish to answer the call.
|
"description": "This event is sent by the callee when they wish to answer the call.",
|
||||||
x-weight: 40
|
"x-weight": 40,
|
||||||
allOf:
|
"allOf": [{
|
||||||
- $ref: core-event-schema/room_event.yaml
|
"$ref": "core-event-schema/room_event.yaml"
|
||||||
properties:
|
}],
|
||||||
content:
|
"properties": {
|
||||||
type: object
|
"content": {
|
||||||
allOf:
|
"type": "object",
|
||||||
- $ref: core-event-schema/call_event.yaml
|
"allOf": [{
|
||||||
properties:
|
"$ref": "core-event-schema/call_event.yaml"
|
||||||
answer:
|
}],
|
||||||
type: object
|
"properties": {
|
||||||
title: Answer
|
"answer": {
|
||||||
description: The session description object
|
"type": "object",
|
||||||
properties:
|
"title": "Answer",
|
||||||
type:
|
"description": "The session description object",
|
||||||
type: string
|
"properties": {
|
||||||
enum:
|
"type": {
|
||||||
- answer
|
"type": "string",
|
||||||
description: The type of session description.
|
"enum": ["answer"],
|
||||||
sdp:
|
"description": "The type of session description."
|
||||||
type: string
|
},
|
||||||
description: The SDP text of the session description.
|
"sdp": {
|
||||||
required:
|
"type": "string",
|
||||||
- type
|
"description": "The SDP text of the session description."
|
||||||
- sdp
|
}
|
||||||
sdp_stream_metadata:
|
},
|
||||||
$ref: components/sdp_stream_metadata.yaml
|
"required": ["type", "sdp"]
|
||||||
required:
|
},
|
||||||
- answer
|
"sdp_stream_metadata": {
|
||||||
type:
|
"$ref": "components/sdp_stream_metadata.yaml"
|
||||||
type: string
|
}
|
||||||
enum:
|
},
|
||||||
- m.call.answer
|
"required": ["answer"]
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["m.call.answer"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,53 @@
|
||||||
$schema: https://json-schema.org/draft/2020-12/schema
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
type: object
|
"type": "object",
|
||||||
description: This event is sent by the caller when they wish to establish a call.
|
"description": "This event is sent by the caller when they wish to establish a call.",
|
||||||
x-weight: 10
|
"x-weight": 10,
|
||||||
allOf:
|
"allOf": [{
|
||||||
- $ref: core-event-schema/room_event.yaml
|
"$ref": "core-event-schema/room_event.yaml"
|
||||||
properties:
|
}],
|
||||||
content:
|
"properties": {
|
||||||
type: object
|
"content": {
|
||||||
allOf:
|
"type": "object",
|
||||||
- $ref: core-event-schema/call_event.yaml
|
"allOf": [{
|
||||||
properties:
|
"$ref": "core-event-schema/call_event.yaml"
|
||||||
offer:
|
}],
|
||||||
type: object
|
"properties": {
|
||||||
title: Offer
|
"offer": {
|
||||||
description: The session description object
|
"type": "object",
|
||||||
properties:
|
"title": "Offer",
|
||||||
type:
|
"description": "The session description object",
|
||||||
type: string
|
"properties": {
|
||||||
enum:
|
"type": {
|
||||||
- offer
|
"type": "string",
|
||||||
description: The type of session description.
|
"enum": ["offer"],
|
||||||
sdp:
|
"description": "The type of session description."
|
||||||
type: string
|
},
|
||||||
description: The SDP text of the session description.
|
"sdp": {
|
||||||
required:
|
"type": "string",
|
||||||
- type
|
"description": "The SDP text of the session description."
|
||||||
- sdp
|
}
|
||||||
lifetime:
|
},
|
||||||
type: integer
|
"required": ["type", "sdp"]
|
||||||
description: The time in milliseconds that the invite is valid for. Once the invite age exceeds this value, clients should discard it. They should also no longer show the call as awaiting an answer in the UI.
|
},
|
||||||
invitee:
|
"lifetime": {
|
||||||
type: string
|
"type": "integer",
|
||||||
description: The ID of the user being called. If omitted, any user in the room can answer.
|
"description": "The time in milliseconds that the invite is valid for. Once the invite age exceeds this value, clients should discard it. They should also no longer show the call as awaiting an answer in the UI."
|
||||||
x-addedInMatrixVersion: '1.7'
|
},
|
||||||
format: mx-user-id
|
"invitee": {
|
||||||
pattern: "^@"
|
"type": "string",
|
||||||
sdp_stream_metadata:
|
"description": "The ID of the user being called. If omitted, any user in the room can answer.",
|
||||||
$ref: components/sdp_stream_metadata.yaml
|
"x-addedInMatrixVersion": "1.7"
|
||||||
required:
|
},
|
||||||
- offer
|
"sdp_stream_metadata": {
|
||||||
- lifetime
|
"$ref": "components/sdp_stream_metadata.yaml"
|
||||||
type:
|
}
|
||||||
type: string
|
},
|
||||||
enum:
|
"required": ["offer", "lifetime"]
|
||||||
- m.call.invite
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["m.call.invite"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,29 @@
|
||||||
$schema: https://json-schema.org/draft/2020-12/schema
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
type: object
|
"type": "object",
|
||||||
description: This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.
|
"description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.",
|
||||||
x-addedInMatrixVersion: '1.7'
|
"x-addedInMatrixVersion": "1.7",
|
||||||
x-weight: 50
|
"x-weight": 50,
|
||||||
allOf:
|
"allOf": [{
|
||||||
- $ref: core-event-schema/room_event.yaml
|
"$ref": "core-event-schema/room_event.yaml"
|
||||||
properties:
|
}],
|
||||||
content:
|
"properties": {
|
||||||
type: object
|
"content": {
|
||||||
allOf:
|
"type": "object",
|
||||||
- $ref: core-event-schema/call_event.yaml
|
"allOf": [{
|
||||||
properties:
|
"$ref": "core-event-schema/call_event.yaml"
|
||||||
selected_party_id:
|
}],
|
||||||
type: string
|
"properties": {
|
||||||
description: The `party_id` field from the answer event that the caller chose.
|
"selected_party_id": {
|
||||||
required:
|
"type": "string",
|
||||||
- selected_party_id
|
"description": "The `party_id` field from the answer event that the caller chose."
|
||||||
type:
|
},
|
||||||
type: string
|
},
|
||||||
enum:
|
"required": ["selected_party_id"]
|
||||||
- m.call.select_answer
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["m.call.select_answer"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ properties:
|
||||||
type: string
|
type: string
|
||||||
x-addedInMatrixVersion: "1.4"
|
x-addedInMatrixVersion: "1.4"
|
||||||
description: |-
|
description: |-
|
||||||
The [thread root](/client-server-api/#threading)'s
|
The root thread event's ID (or `main`) for which
|
||||||
[event ID](/appendices#event-ids) (or `main`) for which
|
thread this receipt is intended to be under. If
|
||||||
thread this receipt is intended to be under. If not
|
not specified, the read receipt is *unthreaded*
|
||||||
specified, the read receipt is *unthreaded* (default).
|
(default).
|
||||||
"m.read.private":
|
"m.read.private":
|
||||||
type: object
|
type: object
|
||||||
description: |-
|
description: |-
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,29 @@
|
||||||
$schema: https://json-schema.org/draft/2020-12/schema
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
type: object
|
"type": "object",
|
||||||
title: Typing Event
|
"title": "Typing Event",
|
||||||
description: Informs the client of the list of users currently typing.
|
"description": "Informs the client of the list of users currently typing.",
|
||||||
allOf:
|
"allOf": [{
|
||||||
- $ref: core-event-schema/event.yaml
|
"$ref": "core-event-schema/event.yaml"
|
||||||
properties:
|
}],
|
||||||
content:
|
"properties": {
|
||||||
type: object
|
"content": {
|
||||||
properties:
|
"type": "object",
|
||||||
user_ids:
|
"properties": {
|
||||||
type: array
|
"user_ids": {
|
||||||
items:
|
"type": "array",
|
||||||
type: string
|
"items": {
|
||||||
format: mx-user-id
|
"type": "string"
|
||||||
pattern: "^@"
|
},
|
||||||
description: The list of user IDs typing in this room, if any.
|
"description": "The list of user IDs typing in this room, if any."
|
||||||
required:
|
}
|
||||||
- user_ids
|
},
|
||||||
type:
|
"required": ["user_ids"]
|
||||||
type: string
|
},
|
||||||
enum:
|
"type": {
|
||||||
- m.typing
|
"type": "string",
|
||||||
required:
|
"enum": ["m.typing"]
|
||||||
- type
|
}
|
||||||
- content
|
},
|
||||||
|
"required": ["type", "content"]
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue