Skip to content

Commit c4db688

Browse files
turt2liveclokeprichvdh
authored
Spec /relations and aggregations (#1062)
* Commit to show changes to rich replies section * Move rich replies to a module * Add remainder of MSC2674 * Pivot away from MSC3440: Threads * Add changelog entries so far * Make a note for why we have aggregations/relations if nothing uses it * Outright remove threads references Apparently this breaks the table of contents * Define MSC2675 * Define MSC3666 * Add note for rich replies? * Update content/client-server-api/_index.md Co-authored-by: Patrick Cloke <[email protected]> * Clarify how ignoring works for aggregations. * Try to clarify redactions a bit * Clarify using parent/child language * Add missing bits of MSC2675 * Add changelog for aggregations * Appease the linters * Update data/api/client-server/relations.yaml Co-authored-by: Patrick Cloke <[email protected]> * Apply suggestions from code review Co-authored-by: Richard van der Hoff <[email protected]> * Apply suggestions from code review Co-authored-by: Richard van der Hoff <[email protected]> * Try to clarify the return of /relations * Fix required attribute * Fix wording round 1 * Try to fix pagination * Copy/paste the endpoint to make Open API happy * Fix code block examples for rich replies * Apply suggestions from code review Co-authored-by: Richard van der Hoff <[email protected]> * Apply suggestions on all 3 endpoints * Fix description of relationships API * Fix warning about server-side aggregation/bundling Co-authored-by: Patrick Cloke <[email protected]> Co-authored-by: Richard van der Hoff <[email protected]>
1 parent f14e181 commit c4db688

File tree

8 files changed

+875
-163
lines changed

8 files changed

+875
-163
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Relax the restrictions on Rich Replies, as per [MSC3676](https://github.com/matrix-org/matrix-spec-proposals/pull/3676).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Describe a structured system for event relationships, as per [MSC2674](https://github.com/matrix-org/matrix-spec-proposals/pull/2674).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Describe how relationships between events can be "aggregated", as per [MSC2675](https://github.com/matrix-org/matrix-spec-proposals/pull/2675) and [MSC3666](https://github.com/matrix-org/matrix-spec-proposals/pull/3666).

content/client-server-api/_index.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,16 @@ There are several APIs provided to `GET` events for a room:
17981798

17991799
### Sending events to a room
18001800

1801+
{{% boxes/note %}}
1802+
{{% added-in v="1.3" %}}
1803+
1804+
Servers might need to post-process some events if they
1805+
[relate to](#forming-relationships-between-events) another event. The event's
1806+
relationship type (`rel_type`) determines any restrictions which might apply,
1807+
such as the user only being able to send one event of a given type in relation
1808+
to another.
1809+
{{% /boxes/note %}}
1810+
18011811
{{% http-api spec="client-server" api="room_state" %}}
18021812

18031813
**Examples**
@@ -1888,6 +1898,216 @@ the topic to be removed from the room.
18881898

18891899
{{% http-api spec="client-server" api="redaction" %}}
18901900

1901+
### Forming relationships between events
1902+
1903+
{{% changed-in v="1.3" %}}
1904+
1905+
In some cases it is desirable to logically associate one event's contents with
1906+
another event's contents — for example, when replying to a message, editing an
1907+
event, or simply looking to add context for an event's purpose.
1908+
1909+
Events are related to each other in a parent/child structure, where any event can
1910+
become a parent by simply having a child event point at it. Parent events do not
1911+
define their children, instead relying on the children to describe their parent.
1912+
1913+
The relationship between a child and its parent event is described in the child
1914+
event's `content` as `m.relates_to` (defined below). A child event can point at
1915+
any other event, including another child event, to build the relationship so long
1916+
as both events are in the same room, however additional restrictions might be imposed
1917+
by the type of the relationship (the `rel_type`).
1918+
1919+
{{% boxes/note %}}
1920+
Child events can point at other child events, forming a chain of events. These chains
1921+
can naturally take the shape of a tree if two independent children point at a single
1922+
parent event, for example.
1923+
{{% /boxes/note %}}
1924+
1925+
To allow the server to aggregate and find child events for a parent, the `m.relates_to`
1926+
key of an event MUST be included in the plaintext copy of the event. It cannot be
1927+
exclusively recorded in the encrypted payload as the server cannot decrypt the event
1928+
for processing.
1929+
1930+
{{% boxes/warning %}}
1931+
If an encrypted event contains an `m.relates_to` in its payload, it should be
1932+
ignored and instead favour the plaintext `m.relates_to` copy (including when there
1933+
is no plaintext copy). This is to ensure the client's behaviour matches the server's
1934+
capability to handle relationships.
1935+
{{% /boxes/warning %}}
1936+
1937+
Relationships which don't match the schema, or which break the rules of a relationship,
1938+
are simply ignored. An example might be the parent and child being in different
1939+
rooms, or the relationship missing properties required by the schema below. Clients
1940+
handling such invalid relationships should show the events independently of each
1941+
other, optionally with an error message.
1942+
1943+
{{% boxes/note %}}
1944+
While this specification describes an `m.relates_to` object containing a `rel_type`, there
1945+
is not currently any relationship type which uses this structure. Replies, described below,
1946+
form their relationship outside of the `rel_type` as a legacy type of relationship. Future
1947+
versions of the specification might change replies to better match the relationship structures.
1948+
1949+
Custom `rel_type`s can, and should, still use the schema described above for relevant
1950+
behaviour.
1951+
{{% /boxes/note %}}
1952+
1953+
`m.relates_to` is defined as follows:
1954+
1955+
{{% definition path="api/client-server/definitions/m.relates_to" %}}
1956+
1957+
#### Relationship types
1958+
1959+
This specification describes the following relationship types:
1960+
1961+
* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
1962+
1963+
#### Aggregations
1964+
1965+
{{% added-in v="1.3" %}}
1966+
1967+
Some child events can be "aggregated" by the server, depending on their
1968+
`rel_type`. This can allow a set of child events to be summarised to the client without
1969+
the client needing the child events themselves.
1970+
1971+
An example of this might be that a `rel_type` requires an extra `key` field which, when
1972+
appropriately specified, would mean that the client receives a total count for the number
1973+
of times that `key` was used by child events.
1974+
1975+
The actual aggregation format depends on the `rel_type`.
1976+
1977+
{{% boxes/note %}}
1978+
This specification does not currently describe any `rel_type`s which require
1979+
aggregation. This functionality forms a framework for future extensions.
1980+
{{% /boxes/note %}}
1981+
1982+
Aggregations are sometimes automatically included by a server alongside the parent
1983+
event. This is known as a "bundled aggregation" or "bundle" for simplicity. The
1984+
act of doing this is "bundling".
1985+
1986+
When an event is served to the client through the APIs listed below, a `m.relations` property
1987+
is included under `unsigned` if the event has child events which can be aggregated and point
1988+
at it. The `m.relations` property is an object keyed by `rel_type` and value being the type-specific
1989+
aggregated format for that `rel_type`, also known as the bundle.
1990+
1991+
For example (unimportant fields not included):
1992+
1993+
```json
1994+
{
1995+
"event_id": "$my_event",
1996+
"unsigned": {
1997+
"m.relations": {
1998+
"org.example.possible_annotations": [
1999+
{
2000+
"key": "👍",
2001+
"origin_server_ts": 1562763768320,
2002+
"count": 3
2003+
},
2004+
{
2005+
"key": "👎",
2006+
"origin_server_ts": 1562763768320,
2007+
"count": 1
2008+
}
2009+
],
2010+
"org.example.possible_thread": {
2011+
"current_server_participated": true,
2012+
"count": 7,
2013+
"latest_event": {
2014+
"event_id": "$another_event",
2015+
"content": {
2016+
"body": "Hello world"
2017+
}
2018+
}
2019+
}
2020+
}
2021+
}
2022+
}
2023+
```
2024+
2025+
Note how the `org.example.possible_annotations` bundle is an array compared to the
2026+
`org.example.possible_thread` bundle where the server is summarising the state of
2027+
the relationship in a single object. Both are valid ways to aggregate, and their
2028+
exact types depend on the `rel_type`.
2029+
2030+
{{% boxes/warning %}}
2031+
State events do not currently receive bundled aggregations. This is not
2032+
necessarily a deliberate design decision, and MSCs which aim to fix this are welcome.
2033+
{{% /boxes/warning %}}
2034+
2035+
The endpoints where the server *should* include bundled aggregations are:
2036+
2037+
* [`GET /rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages)
2038+
* [`GET /rooms/{roomId}/context/{eventId}`](#get_matrixclientv3roomsroomidcontexteventid)
2039+
* [`GET /rooms/{roomId}/event/{eventId}`](#get_matrixclientv3roomsroomideventeventid)
2040+
* [`GET /rooms/{roomId}/relations/{eventId}`](#get_matrixclientv1roomsroomidrelationseventid)
2041+
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}`](#get_matrixclientv1roomsroomidrelationseventidreltype)
2042+
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}/{eventType}`](#get_matrixclientv1roomsroomidrelationseventidreltypeeventtype)
2043+
* [`GET /sync`](#get_matrixclientv3sync) when the relevant section has a `limited` value
2044+
of `true`.
2045+
* [`POST /search`](#post_matrixclientv3search) for any matching events under `room_events`.
2046+
2047+
{{% boxes/note %}}
2048+
The server is **not** required to return bundled aggregations on deprecated endpoints
2049+
such as `/initialSync`.
2050+
{{% /boxes/note %}}
2051+
2052+
While this functionality allows the client to see what was known to the server at the
2053+
time of handling, the client should continue to aggregate locally if it is aware of
2054+
the relationship type's behaviour. For example, a client might increment a `count`
2055+
on a parent event's bundle if it saw a new child event which referenced that parent.
2056+
2057+
The bundle provided by the server only includes child events which were known at the
2058+
time the client would receive the bundle. For example, in a single `/sync` response
2059+
with the parent and multiple child events the child events would have already been
2060+
included on the parent's `m.relations` field. Events received in future syncs would
2061+
need to be aggregated manually by the client.
2062+
2063+
{{% boxes/note %}}
2064+
Events from [ignored users](#ignoring-users) do not appear in the aggregation
2065+
from the server, however clients might still have events from ignored users cached. Like
2066+
with normal events, clients will need to de-aggregate child events sent by ignored users to
2067+
avoid them being considered in counts. Servers must additionally ensure they do not
2068+
consider child events from ignored users when preparing a bundle for the client.
2069+
{{% /boxes/note %}}
2070+
2071+
When a parent event is redacted, the child events which pointed to that parent remain, however
2072+
when a child event is redacted then the relationship is broken. Therefore, the server needs
2073+
to de-aggregate or disassociate the event once the relationship is lost. Clients with local
2074+
aggregation or which handle redactions locally should do the same.
2075+
2076+
It is suggested that clients perform local echo on aggregations — for instance, aggregating
2077+
a new child event into a bundle optimistically until the server returns a failure or the client
2078+
gives up on sending the event, at which point the event should be de-aggregated and an
2079+
error or similar shown. The client should be cautious to not aggregate an event twice if
2080+
it has already optimistically aggregated the event. Clients are encouraged to take this
2081+
a step further to additionally track child events which target unsent/pending events,
2082+
likely using the transaction ID as a temporary event ID until a proper event ID is known.
2083+
2084+
{{% boxes/warning %}}
2085+
Due to history visibility restrictions, child events might not be visible to the user
2086+
if they are in a section of history the user cannot see. This means any bundles which would
2087+
normally include those events will be lacking them and the client will not be able to
2088+
locally aggregate the events either — relating events of importance (such as votes) should
2089+
take into consideration history visibility.
2090+
2091+
Additionally, if the server is missing portions of the room history then it may not be
2092+
able to accurately aggregate the events.
2093+
{{% /boxes/warning %}}
2094+
2095+
#### Relationships API
2096+
2097+
{{% added-in v="1.3" %}}
2098+
2099+
To retrieve the child events for a parent from the server, the client can call the
2100+
following endpoint.
2101+
2102+
This endpoint is particularly useful if the client has lost context on the aggregation for
2103+
a parent event and needs to rebuild/verify it.
2104+
2105+
{{% boxes/note %}}
2106+
Because replies do not use `rel_type`, they will not be accessible via this API.
2107+
{{% /boxes/note %}}
2108+
2109+
{{% http-api spec="client-server" api="relations" %}}
2110+
18912111
## Rooms
18922112

18932113
### Types
@@ -2294,6 +2514,7 @@ that profile.
22942514
| Module / Profile | Web | Mobile | Desktop | CLI | Embedded |
22952515
|------------------------------------------------------------|-----------|----------|----------|----------|----------|
22962516
| [Instant Messaging](#instant-messaging) | Required | Required | Required | Required | Optional |
2517+
| [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional |
22972518
| [Direct Messaging](#direct-messaging) | Required | Required | Required | Required | Optional |
22982519
| [Mentions](#user-room-and-group-mentions) | Required | Required | Required | Optional | Optional |
22992520
| [Presence](#presence) | Required | Required | Required | Required | Optional |
@@ -2373,6 +2594,7 @@ applications, they are not intended to be fully-fledged communication
23732594
systems.
23742595

23752596
{{% cs-module name="instant_messaging" %}}
2597+
{{% cs-module name="rich_replies" %}}
23762598
{{% cs-module name="voip_events" %}}
23772599
{{% cs-module name="typing_notifications" %}}
23782600
{{% cs-module name="receipts" %}}

0 commit comments

Comments
 (0)