Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec /relations and aggregations #1062

Merged
merged 31 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1d70a8d
Commit to show changes to rich replies section
turt2live May 5, 2022
03c4638
Move rich replies to a module
turt2live May 5, 2022
01cd76e
Add remainder of MSC2674
turt2live May 14, 2022
ff03381
Pivot away from MSC3440: Threads
turt2live May 14, 2022
b319d2f
Add changelog entries so far
turt2live May 14, 2022
9e7929c
Make a note for why we have aggregations/relations if nothing uses it
turt2live May 14, 2022
29c9465
Outright remove threads references
turt2live May 17, 2022
1435d06
Define MSC2675
turt2live May 18, 2022
7a92cf5
Define MSC3666
turt2live May 18, 2022
76e3611
Add note for rich replies?
turt2live May 18, 2022
2063d11
Update content/client-server-api/_index.md
turt2live May 27, 2022
109bfb2
Clarify how ignoring works for aggregations.
turt2live May 27, 2022
0d35037
Try to clarify redactions a bit
turt2live May 27, 2022
532b06b
Clarify using parent/child language
turt2live May 27, 2022
9fa50a7
Add missing bits of MSC2675
turt2live May 27, 2022
753fd81
Add changelog for aggregations
turt2live May 27, 2022
d9004d7
Appease the linters
turt2live May 27, 2022
42e5c4d
Update data/api/client-server/relations.yaml
turt2live May 27, 2022
f8d667a
Apply suggestions from code review
turt2live Jun 2, 2022
315b327
Apply suggestions from code review
turt2live Jun 2, 2022
2cc631e
Try to clarify the return of /relations
turt2live Jun 2, 2022
b5b6fd9
Fix required attribute
turt2live Jun 2, 2022
09422a3
Fix wording round 1
turt2live Jun 7, 2022
0f65b2f
Try to fix pagination
turt2live Jun 7, 2022
340f9e5
Copy/paste the endpoint to make Open API happy
turt2live Jun 7, 2022
c02e1f1
Fix code block examples for rich replies
turt2live Jun 7, 2022
b509444
Apply suggestions from code review
turt2live Jun 8, 2022
5bb8b3e
Apply suggestions on all 3 endpoints
turt2live Jun 8, 2022
13a43c0
Fix description of relationships API
turt2live Jun 8, 2022
a00e70e
Fix warning about server-side aggregation/bundling
turt2live Jun 8, 2022
50b4811
Merge remote-tracking branch 'origin/travis/spec/aggregations' into t…
turt2live Jun 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 45 additions & 47 deletions content/client-server-api/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1846,18 +1846,18 @@ the topic to be removed from the room.
{{% changed-in v="1.3" %}}
richvdh marked this conversation as resolved.
Show resolved Hide resolved

In some cases it is desirable to logically associate one event's contents with
another event's contents. For example, when replying to a message, editing an
another event's contents — for example, when replying to a message, editing an
event, or simply looking to add context for an event's purpose.

Events are related to each other in a parent/child structure, where any event can
become a parent by simply having a child event point at it. Parent events do not
define their children, instead relying on the children to describe their parent.

The relationship between a child and it's parent event is described in the child
The relationship between a child and its parent event is described in the child
event's `content` as `m.relates_to` (defined below). A child event can point at
any other event, including another child event, to build the relationship so long
as both events are in the same room, however additional restrictions might be imposed
by the `rel_type` itself.
by the type of the relationship (the `rel_type`).

{{% boxes/note %}}
Child events can point at other child events, forming a chain of events. These chains
Expand All @@ -1877,45 +1877,37 @@ is no plaintext copy). This is to ensure the client's behaviour matches the serv
capability to handle relationships.
{{% /boxes/warning %}}

Improperly formed or structured relationships are simply ignored. For example, the
child and parent events being in different rooms or the relationship missing fields
required by the schema below. The events would appear independent of each other or
optionally with an error message (if rendered/handled by the client exclusively).

`m.relates_to` is described as follows:

{{% definition path="api/client-server/definitions/m.relates_to" %}}

#### Relationship types
Relationships which don't match the schema, or which break the rules of a relationship,
are simply ignored. Such an example might be the parent and child being in different
turt2live marked this conversation as resolved.
Show resolved Hide resolved
rooms or the relationship missing properties required by the schema below. The events
turt2live marked this conversation as resolved.
Show resolved Hide resolved
would appear independent of each other or optionally with an error message (if
rendered/handled by the client exclusively).
turt2live marked this conversation as resolved.
Show resolved Hide resolved

{{% boxes/note %}}
While this specification describes an `m.relates_to` object containing a `rel_type`, there
is not currently any relationship type which uses this structure. Replies, described below,
form their relationship outside of the `rel_type` in order to allow other, future, relationship
types to make use of replies in addition to their normal behaviour.
form their relationship outside of the `rel_type` as a legacy type of relationship. Future
versions of the specification might change replies to better match the relationship structures.

Custom `rel_type`s can, and should, still use the schema described above for relevant
behaviour.
{{% /boxes/note %}}

This specification describes the following relationship types:
`m.relates_to` is defined as follows:

* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
{{% definition path="api/client-server/definitions/m.relates_to" %}}

{{% boxes/note %}}
This specification does not currently define any relation type which requires
aggregation or has restrictions, however [namespaced](/appendices#identifier-grammar)
relationship types might have these restrictions.
#### Relationship types

Future versions of this specification are expected to require certain behaviours
or aggregation of related events.
{{% /boxes/note %}}
This specification describes the following relationship types:

* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).

#### Aggregations

{{% added-in v="1.3" %}}
richvdh marked this conversation as resolved.
Show resolved Hide resolved

Some child events can be "aggregated" or "bundled" by the server, depending on their
Some child events can be "aggregated" by the server, depending on their
`rel_type`. This can allow a set of child events to be summarised to the client without
the client needing the child events themselves.

Expand All @@ -1927,17 +1919,17 @@ The actual aggregation format depends on the `rel_type`.

{{% boxes/note %}}
This specification does not currently describe any `rel_type` which require
turt2live marked this conversation as resolved.
Show resolved Hide resolved
aggregation, however [namespaced](/appendices#identifier-grammar) relationship
types might have aggregation behaviour.
aggregation. This functionality forms a framework for future extensions.
{{% /boxes/note %}}

When aggregations are summarised on an event, it is known as a "bundled aggregation"
or "bundle" for simplicity. The act of doing this is "bundling".
Aggregations are sometimes automatically included by a server alongside the parent
event. This This is known as a "bundled aggregation" or "bundle" for simplicity. The
turt2live marked this conversation as resolved.
Show resolved Hide resolved
act of doing this is "bundling".

When an event is served to the client through the APIs listed below, a `m.relations` field
is included under `unsigned` if the event has child events which point at it. The `m.relations`
field is an object keyed by `rel_type` and value being the type-specific format for that
`rel_type`, also known as the bundle.
When an event is served to the client through the APIs listed below, a `m.relations` property
is included under `unsigned` if the event has child events which can be aggregated and point
at it. The `m.relations` property is an object keyed by `rel_type` and value being the type-specific
aggregated format for that `rel_type`, also known as the bundle.

For example (unimportant fields not included):

Expand Down Expand Up @@ -1975,26 +1967,28 @@ For example (unimportant fields not included):

Note how the `org.example.possible_annotations` bundle is an array compared to the
`org.example.possible_thread` bundle where the server is summarising the state of
the relationship in a single object. Both are valid bundles, and their exact types
depend on the `rel_type`.
the relationship in a single object. Both are valid ways to aggregate, and their
exact types depend on the `rel_type`.

{{% boxes/warning %}}
State events do not currently receive the `m.relations` unsigned field. This is not
State events do not currently receive bundled aggregations. This is not
necessarily a deliberate design decision, and MSCs which aim to fix this are welcome.
{{% /boxes/warning %}}

The endpoints where the server *should* include the `m.relations` unsigned field are:
The endpoints where the server *should* include bundled aggregations are:

* [`GET /rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages)
* [`GET /rooms/{roomId}/context/{eventId}`](#get_matrixclientv3roomsroomidcontexteventid)
* [`GET /rooms/{roomId}/event/{eventId}`](#get_matrixclientv3roomsroomideventeventid)
* [`GET /rooms/{roomId}/relations`](#get_matrixclientv3roomsroomidrelations)
* [`GET /rooms/{roomId}/relations/{eventId}`](#get_matrixclientv1roomsroomidrelationseventid)
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}`](#get_matrixclientv1roomsroomidrelationseventidreltype)
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}/{eventType}`](#get_matrixclientv1roomsroomidrelationseventidreltypeeventtype)
* [`GET /sync`](#get_matrixclientv3sync) when the relevant section has a `limited` value
of `true`.
* [`POST /search`](#post_matrixclientv3search) for any matching events under `room_events`.

{{% boxes/note %}}
The server is **not** required to return bundles/aggregations on deprecated endpoints
The server is **not** required to return bundled aggregations on deprecated endpoints
such as `/initialSync`.
{{% /boxes/note %}}

Expand All @@ -2010,7 +2004,7 @@ included on the parent's `m.relations` field. Events received in future syncs wo
need to be aggregated manually by the client.

{{% boxes/note %}}
Events from [ignored users](#ignoring-users) do not appear in the bundle or aggregation
Events from [ignored users](#ignoring-users) do not appear in the aggregation
from the server, however clients might still have events from ignored users cached. Like
with normal events, clients will need to de-aggregate child events sent by ignored users to
avoid them being considered in counts. Servers must additionally ensure they do not
Expand All @@ -2022,7 +2016,7 @@ when a child event is redacted then the relationship is broken. Therefore, the s
to de-aggregate or disassociate the event once the relationship is lost. Clients with local
aggregation or which handle redactions locally should do the same.

It is suggested that clients perform local echo on aggregations. For instance, aggregating
It is suggested that clients perform local echo on aggregations — for instance, aggregating
a new child event into a bundle optimistically until the server returns a failure or the client
richvdh marked this conversation as resolved.
Show resolved Hide resolved
gives up on sending the event, at which point the event should be de-aggregated and an
error or similar shown. The client should be cautious to not aggregate an event twice if
Expand All @@ -2032,7 +2026,7 @@ likely using the transaction ID as a temporary event ID until a proper event ID

{{% boxes/warning %}}
Due to history visibility restrictions, child events might not be visible to the user
if they are in a section of history the user cannot see. This can mean inaccurate bundles
if they are in a section of history the user cannot see. This can mean inaccurate aggregations
for events that are "out of range".

Additionally, if the server is missing portions of the room history then it may not be
Expand All @@ -2042,12 +2036,16 @@ able to accurately aggregate the events.
#### Relationships API
turt2live marked this conversation as resolved.
Show resolved Hide resolved

To retrieve the child events for a parent from the server, the client can call the
following endpoint with relevant information. This endpoint does not aggregate the child
events and is instead paginated: clients can perform local aggregation if needed. This
allows clients to retrieve child events which do not require aggregation but still make
use of `rel_type`.
following endpoint. The events returned might require local aggregation by the client,
however if those same events have bundles of their own then they should be present. A
turt2live marked this conversation as resolved.
Show resolved Hide resolved
hypothetical example would be retrieving all responses to a thread, and those responses
might have emoji reactions made against them: the client will need to construct the
thread itself, but the events in the thread should have a reactions bundle on them.

The lack of aggregation behaviour allows clients to retrieve child events which don't
require aggregation, but do make use of a `rel_type`.
turt2live marked this conversation as resolved.
Show resolved Hide resolved

This endpoint is particularly useful if the client has lost context on the bundle for
This endpoint is particularly useful if the client has lost context on the aggregation for
a parent event and needs to rebuild/verify it.

{{% boxes/note %}}
Expand Down
22 changes: 11 additions & 11 deletions content/client-server-api/modules/rich_replies.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ type: module

{{% changed-in v="1.3" %}}

More common on [`m.room.message`](#mroommessage) events, rich replies are a
Rich replies are a
special kind of [relationship](#forming-relationships-between-events) which
effectively quotes the referenced event for the client to render/process how
it wishes.
it wishes. They are normally used with [`m.room.message`](#mroommessage) events.

{{% boxes/note %}}
Until v1.3 of the spec, rich replies were limited to `m.room.message` events
Expand All @@ -25,12 +25,12 @@ When possible, events SHOULD include a [fallback representation](#fallbacks-for-
to allow clients which do not render rich replies to still see something which
appears to be a quoted reply.

Though rich replies are forming a relationship to another event, they do not
Though rich replies form a relationship to another event, they do not
use `rel_type` to create this relationship. Instead, a subkey named `m.in_reply_to`
is used to describe the reply's relationship, leaving the other keys of
is used to describe the reply's relationship, leaving the other properties of
`m.relates_to` to describe the primary relationship of the event. This means
that if an event is simply in reply to another event, without further relationship,
the `rel_type` and `event_id` keys of `m.relates_to` become *optional*.
the `rel_type` and `event_id` properties of `m.relates_to` become *optional*.

An example reply would be:

Expand Down Expand Up @@ -71,7 +71,7 @@ This is where the reply goes
The `formatted_body`, if present and using an associated `format` of
`org.matrix.custom.html`, should use the following template:

```
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
Expand Down Expand Up @@ -114,7 +114,7 @@ Using the prefix sequence, the first line of the related event's `body`
should be prefixed with the user's ID, followed by each line being
prefixed with the fallback prefix sequence. For example:

```
```text
> <@alice:example.org> This is the first line
> This is the second line

Expand All @@ -129,7 +129,7 @@ Similar to the fallback for `m.text`, each line gets prefixed with the
fallback prefix sequence. However an asterisk should be inserted before
the user's ID, like so:

```
```text
> * <@alice:example.org> feels like today is going to be a great day

This is the reply
Expand All @@ -138,7 +138,7 @@ This is the reply
The `formatted_body` has a subtle difference for the template where the
asterisk is also inserted ahead of the user's ID:

```
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
Expand All @@ -160,12 +160,12 @@ filename alone may not be descriptive, the related event's `body` should
be considered to be `"sent a file."` such that the output looks similar
to the following:

```
```text
> <@alice:example.org> sent a file.

This is the reply
```
```
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
Expand Down
4 changes: 2 additions & 2 deletions data/api/client-server/definitions/m.relates_to.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
type: object
title: m.relates_to
description: |-
A description of a valid `m.relates_to` definition on a child event. This is contained
Describes the relationship of an event to its parent. This is contained
within the event's `content` alongside other fields for the relevant event type.
example: {
# We deliberately "break" the example by including the top-level field so it renders
Expand All @@ -39,5 +39,5 @@ properties:
such.
event_id:
type: string
description: The parent event ID in the same room this event points/relates to.
description: The event ID of the event that this event relates to.
required: ['rel_type', 'event_id']
Loading