@@ -1798,6 +1798,16 @@ There are several APIs provided to `GET` events for a room:
1798
1798
1799
1799
### Sending events to a room
1800
1800
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
+
1801
1811
{{% http-api spec="client-server" api="room_state" %}}
1802
1812
1803
1813
** Examples**
@@ -1888,6 +1898,216 @@ the topic to be removed from the room.
1888
1898
1889
1899
{{% http-api spec="client-server" api="redaction" %}}
1890
1900
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
+
1891
2111
## Rooms
1892
2112
1893
2113
### Types
@@ -2294,6 +2514,7 @@ that profile.
2294
2514
| Module / Profile | Web | Mobile | Desktop | CLI | Embedded |
2295
2515
| ------------------------------------------------------------| -----------| ----------| ----------| ----------| ----------|
2296
2516
| [ Instant Messaging] ( #instant-messaging ) | Required | Required | Required | Required | Optional |
2517
+ | [ Rich replies] ( #rich-replies ) | Optional | Optional | Optional | Optional | Optional |
2297
2518
| [ Direct Messaging] ( #direct-messaging ) | Required | Required | Required | Required | Optional |
2298
2519
| [ Mentions] ( #user-room-and-group-mentions ) | Required | Required | Required | Optional | Optional |
2299
2520
| [ Presence] ( #presence ) | Required | Required | Required | Required | Optional |
@@ -2373,6 +2594,7 @@ applications, they are not intended to be fully-fledged communication
2373
2594
systems.
2374
2595
2375
2596
{{% cs-module name="instant_messaging" %}}
2597
+ {{% cs-module name="rich_replies" %}}
2376
2598
{{% cs-module name="voip_events" %}}
2377
2599
{{% cs-module name="typing_notifications" %}}
2378
2600
{{% cs-module name="receipts" %}}
0 commit comments