Skip to content

Commit

Permalink
Spec annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Mar 28, 2023
1 parent a21b23d commit c31a073
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelogs/client_server/newsfragments/1475.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `m.annotation` relations (reactions), as per [MSC2677](https://github.com/matrix-org/matrix-spec-proposals/pull/2677).
4 changes: 4 additions & 0 deletions content/client-server-api/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,7 @@ This specification describes the following relationship types:

* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
* [Event replacements](#event-replacements).
* [Event annotations](#event-annotations-and-reactions).
* [Threads](#threading).
* [References](#reference-relations)

Expand Down Expand Up @@ -2579,6 +2580,7 @@ that profile.
| [Moderation policies](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
| [Spaces](#spaces) | Optional | Optional | Optional | Optional | Optional |
| [Event Replacements](#event-replacements) | Optional | Optional | Optional | Optional | Optional |
| [Event Annotations and reactions](#event-annotations-and-reactions) | Optional | Optional | Optional | Optional | Optional |
| [Threading](#threading) | Optional | Optional | Optional | Optional | Optional |
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |

Expand Down Expand Up @@ -2665,5 +2667,7 @@ systems.
{{< cs-module name="moderation_policies" >}}
{{< cs-module name="spaces" >}}
{{< cs-module name="event_replacements" >}}
{{< cs-module name="event_annotations" >}}
{{< cs-module name="threading" >}}
{{< cs-module name="reference_relations" >}}

92 changes: 92 additions & 0 deletions content/client-server-api/modules/event_annotations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
### Event annotations and reactions

{{% added-in v="1.7" %}}

#### `m.annotation` relationship type

Annotations are events that use an [event
relationship](#forming-relationships-between-events) with a `rel_type` of
`m.annotation`.

Annotations are normally used for "reactions": for example, if the user wants
to react to an event with a thumbs-up, then the client sends an annotation
event with the corresponding emoji (👍). Another potential usage is to allow
bots to send an event indicating the success or failure of a command.

Along with the normal properties `event_id` and `rel_type`, an `m.relates_to`
property with `rel_type: m.annotion` should contain a `key` that indicates the
annotation being applied. For example, when reacting with emojis, the key
contains the emoji being used.

An example `m.annotation` relationship is shown below:

```json
"m.relates_to": {
"rel_type": "m.annotation",
"event_id": "$some_event_id",
"key": "👍"
}
```

{{% boxes/note %}}
Any `type` of event is eligible for an annotation, including state events.
{{% /boxes/note %}}

#### Events

{{% event event="m.reaction" %}}

#### Client behaviour {id="annotations-client-behaviour"}

The intention of annotations is that they are counted up, rather than being
displayed individually. Clients must keep count of the number of annotations
with a given event `type` and annotation `key` they observe for each event;
these counts are typically presented alongside the event in the timeline.

When performing this count:

* Each event `type` and annotation `key` should normally be counted
separately, though whether to actually do so is an implementation decision.

* Annotation events sent by [ignored users](#ignoring-users) should be
excluded from the count.

* Multiple identical annotations (i.e., with the same event `type` and
annotation `key`) from the same user (i.e., events with the same `sender`)
should be treated as a single annotation.

* Implementations should ignore any annotation event which refers to an event
which itself has an `m.relates_to` with `rel_type: m.annotation` or
`rel_type: m.replace`. In other words, it is not possible to annotate a
[replacement event](#event-replacements) or an annotation.

* When an annotation is redacted, it is removed from the count.

{{% boxes/note %}}
It is not possible to edit a reaction, since replacement events do not change
`m.relates_to` (see [Applying `m.new_content`](#applying-mnew_content)), and
there is no other meaningful content within `m.reaction`. If a user wishes to
change their reaction, the original reaction should be redacted and a new one
sent in its place.
{{% /boxes/note %}}

#### Server behaviour

##### Avoiding duplicate annotations

Homeservers should prevent users from sending a second annotation for a given
event with identical event `type` and annotation `key` (unless the first event
has been redacted).

Attempts to send such an annotation should be rejected with a 400 error and an
error code of `M_DUPLICATE_ANNOTATION`.

Note that this does not guarantee that duplicate annotations will not arrive
over federation. Clients are responsible for deduplicating received
annotations when [counting annotations](#annotations-client-behaviour).

##### Server-side aggregation of `m.annotation` relationships

`m.annotation` relationships are *not* [aggregated](#aggregations) by the
server. In other words, `m.annotation` is not included in the `m.relations`
property.
25 changes: 25 additions & 0 deletions content/client-server-api/modules/push.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,31 @@ Definition:
}
```

**<a name="mrulereaction"></a>`.m.rule.reaction`**

{{% added-in v="1.7" %}}

Matches any event whose type is `m.room.reaction`. This suppresses notifications for [`m.reaction`](#mreaction) events.

Definition:

```json
{
"rule_id": ".m.rule.reaction",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "type",
"pattern": "m.reaction"
}
],
"actions": []
}
```


**`.m.rule.room.server_acl`**

{{% added-in v="1.4" %}}
Expand Down
11 changes: 11 additions & 0 deletions data/event-schemas/examples/m.reaction.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$ref": "core/room_event.json",
"type": "m.reaction",
"content": {
"m.relates_to": {
"rel_type": "m.annotation",
"event_id": "$some_event_id",
"key": "👍"
}
}
}
37 changes: 37 additions & 0 deletions data/event-schemas/schema/m.reaction.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
allOf:
- $ref: core-event-schema/room_event.yaml
description: |-
Indicates a reaction to a previous event.
Has no defined `content` properties of its own. Its only purpose is to hold an
[`m.relates_to`](/client-server-api/#definition-mrelates_to) property.
Since they contain no content other than `m.relates_to`, `m.reaction` events
are normally not encrypted, as there would be no benefit in doing so.
type: object
properties:
content:
type: object
properties:
m.relates_to:
description: |-
Indicates the event being reacted to, and the type of reaction.
type: object
title: ReactionRelatesTo
properties:
rel_type:
type: string
enum: ["m.annotation"]
event_id:
type: string
description: |-
The event ID of the event that this is a reaction to.
example: "$some_event_id"
key:
type: string
description: |-
An emoji representing the reaction being made. Should include the
unicode emoji presentation selector (`\uFE0F`) for codepoints
which allow it (see the [emoji variation sequences
list](https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-variation-sequences.txt)).
example: "👍"

0 comments on commit c31a073

Please sign in to comment.