mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-03-26 13:04:10 +01:00
Spec MSC2285 (private read receipts)
This commit is contained in:
parent
06ddb862c3
commit
03399e286a
|
|
@ -107,7 +107,19 @@ determined by the push rules which apply to an event.
|
|||
|
||||
When the user updates their read receipt (either by using the API or by
|
||||
sending an event), notifications prior to and including that event MUST
|
||||
be marked as read.
|
||||
be marked as read. Note that users can send both an `m.read` and
|
||||
`m.read.private` receipt, both of which are capable of clearing notifications.
|
||||
|
||||
If the user has both `m.read` and `m.read.private` set in the room then
|
||||
the receipt which is more recent/ahead must be used to determine where
|
||||
the user has read up to. For example, given an ordered set of events A,
|
||||
B, C, and D the `m.read` receipt could be at event C and `m.read.private`
|
||||
at event A - the user is considered to have read up to event C. If the
|
||||
`m.read.private` receipt is then updated to point to B or C, the user's
|
||||
notification state doesn't change (the `m.read` receipt is still more
|
||||
ahead), however if the `m.read.private` receipt were to be updated to
|
||||
event D then the user has read up to D (the `m.read` receipt is now
|
||||
behind the `m.read.private` receipt).
|
||||
|
||||
##### Push Rules
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,16 @@ The client cannot update fully read markers by directly modifying the
|
|||
`m.fully_read` account data event. Instead, the client must make use of
|
||||
the read markers API to change the values.
|
||||
|
||||
{{< changed-in v="1.4" >}} `m.read.private` receipts can now be sent from
|
||||
`/read_markers`.
|
||||
|
||||
The read markers API can additionally update the user's read receipt
|
||||
(`m.read`) location in the same operation as setting the fully read
|
||||
marker location. This is because read receipts and read markers are
|
||||
commonly updated at the same time, and therefore the client might wish
|
||||
to save an extra HTTP call. Providing an `m.read` location performs the
|
||||
same task as a request to `/receipt/m.read/$event:example.org`.
|
||||
(`m.read` or `m.read.private`) location in the same operation as setting
|
||||
the fully read marker location. This is because read receipts and read
|
||||
markers are commonly updated at the same time, and therefore the client
|
||||
might wish to save an extra HTTP call. Providing `m.read` and/or
|
||||
`m.read.private` performs the same task as a request to
|
||||
[`/receipt/{receiptType}/{eventId}`](#post_matrixclientv3roomsroomidreceiptreceipttypeeventid).
|
||||
|
||||
{{% http-api spec="client-server" api="read_markers" %}}
|
||||
|
||||
|
|
@ -44,8 +48,9 @@ same task as a request to `/receipt/m.read/$event:example.org`.
|
|||
|
||||
The server MUST prevent clients from setting `m.fully_read` directly in
|
||||
room account data. The server must additionally ensure that it treats
|
||||
the presence of `m.read` in the `/read_markers` request the same as how
|
||||
it would for a request to `/receipt/m.read/$event:example.org`.
|
||||
the presence of `m.read` and `m.read.private` in the `/read_markers`
|
||||
request the same as how it would for a request to
|
||||
[`/receipt/{receiptType}/{eventId}`](#post_matrixclientv3roomsroomidreceiptreceipttypeeventid).
|
||||
|
||||
Upon updating the `m.fully_read` event due to a request to
|
||||
`/read_markers`, the server MUST send the updated account data event
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@ type: module
|
|||
|
||||
### Receipts
|
||||
|
||||
{{< changed-in v="1.4" >}} Added private read receipts.
|
||||
|
||||
This module adds in support for receipts. These receipts are a form of
|
||||
acknowledgement of an event. This module defines a single
|
||||
acknowledgement: `m.read` which indicates that the user has read up to a
|
||||
given event.
|
||||
acknowledgement of an event. This module defines the `m.read` receipt
|
||||
for indicating that the user has read up to a given event, and `m.read.private`
|
||||
to achieve the same purpose without any other user being aware. Primarily,
|
||||
`m.read.private` is meant to clear [notifications](#receiving-notifications)
|
||||
without advertising read-up-to status to others.
|
||||
|
||||
Sending a receipt for each event can result in sending large amounts of
|
||||
traffic to a homeserver. To prevent this from becoming a problem,
|
||||
|
|
@ -59,12 +63,36 @@ following HTTP APIs.
|
|||
|
||||
{{% http-api spec="client-server" api="receipts" %}}
|
||||
|
||||
##### Private read receipts
|
||||
|
||||
{{% added-in v="1.4" %}}
|
||||
|
||||
Some users would like to clear their [notification counts](#receiving-notifications),
|
||||
but not give away the fact that they've read a particular message yet. To
|
||||
achieve this, clients can send `m.read.private` receipts instead of `m.read`
|
||||
to do exactly that: clear notifications and not broadcast the receipt to
|
||||
other users.
|
||||
|
||||
Servers MUST NOT send the `m.read.private` receipt to any other user than the
|
||||
one which originally sent it.
|
||||
|
||||
Between `m.read` and `m.read.private`, the receipt which is more "ahead" or
|
||||
"recent" is used when determining the highest read-up-to mark. See the
|
||||
[notifications](#receiving-notifications) section for more information on
|
||||
how this affects notification counts.
|
||||
|
||||
If a client sends an `m.read` receipt which is "behind" the `m.read.private`
|
||||
receipt, other users will see that change happen but the sending user will
|
||||
not have their notification counts rewound to that point in time. While
|
||||
uncommon, it is considered valid to have an `m.read` (public) receipt lag
|
||||
several messages behind the `m.read.private` receipt, for example.
|
||||
|
||||
#### Server behaviour
|
||||
|
||||
For efficiency, receipts SHOULD be batched into one event per room
|
||||
before delivering them to clients.
|
||||
|
||||
Receipts are sent across federation as EDUs with type `m.receipt`. The
|
||||
Some receipts are sent across federation as EDUs with type `m.receipt`. The
|
||||
format of the EDUs are:
|
||||
|
||||
```
|
||||
|
|
@ -80,7 +108,8 @@ format of the EDUs are:
|
|||
```
|
||||
|
||||
These are always sent as deltas to previously sent receipts. Currently
|
||||
only a single `<receipt_type>` should be used: `m.read`.
|
||||
only a single `<receipt_type>` should be used: `m.read`. `m.read.private`
|
||||
MUST NOT appear in this federated `m.receipt` EDU.
|
||||
|
||||
#### Security considerations
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ paths:
|
|||
The event ID the read marker should be located at. The
|
||||
event MUST belong to the room.
|
||||
example: "$somewhere:example.org"
|
||||
x-changedInMatrixVersion:
|
||||
1.4: |
|
||||
This property is no longer required.
|
||||
"m.read":
|
||||
type: string
|
||||
description: |-
|
||||
|
|
@ -63,11 +66,19 @@ paths:
|
|||
equivalent to calling `/receipt/m.read/$elsewhere:example.org`
|
||||
and is provided here to save that extra call.
|
||||
example: "$elsewhere:example.org"
|
||||
required: ['m.fully_read']
|
||||
"m.read.private":
|
||||
x-addedInMatrixVersion: "1.4"
|
||||
type: string
|
||||
description: |-
|
||||
The event ID to set the *private* read receipt location at. This
|
||||
equivalent to calling `/receipt/m.read.private/$elsewhere:example.org`
|
||||
and is provided here to save that extra call.
|
||||
example: "$elsewhere:example.org"
|
||||
required: []
|
||||
responses:
|
||||
200:
|
||||
description: |-
|
||||
The read marker, and read receipt if provided, have been updated.
|
||||
The read marker, and read receipt(s) if provided, have been updated.
|
||||
schema:
|
||||
type: object
|
||||
properties: {}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,10 @@ paths:
|
|||
description: The type of receipt to send.
|
||||
required: true
|
||||
x-example: "m.read"
|
||||
enum: ["m.read"]
|
||||
x-changedInMatrixVersion:
|
||||
1.4: |
|
||||
Allow `m.read.private` receipts.
|
||||
enum: ["m.read", "m.read.private"]
|
||||
- in: path
|
||||
type: string
|
||||
name: eventId
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
"@rikj:jki.re": {
|
||||
"ts": 1436451550453
|
||||
}
|
||||
},
|
||||
"m.read.private": {
|
||||
"@self:example.org": {
|
||||
"ts": 1661384801651
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
type: object
|
||||
title: Receipt Event
|
||||
description: Informs the client of new receipts.
|
||||
x-changedInMatrixVersion:
|
||||
1.4: |
|
||||
Added `m.read.private` receipts to the event's `content`.
|
||||
allOf:
|
||||
- $ref: "core-event-schema/event.yaml"
|
||||
properties:
|
||||
|
|
@ -23,7 +26,7 @@ properties:
|
|||
A collection of users who have sent `m.read` receipts for
|
||||
this event.
|
||||
patternProperties:
|
||||
"^@":
|
||||
"^@": &receiptUserMap
|
||||
type: object
|
||||
title: Receipt
|
||||
description: |-
|
||||
|
|
@ -35,8 +38,17 @@ properties:
|
|||
type: integer
|
||||
format: int64
|
||||
description: The timestamp the receipt was sent at.
|
||||
"m.read.private":
|
||||
type: object
|
||||
title: Own User
|
||||
description: |-
|
||||
Similar to `m.read`, the users who have sent `m.read.private`
|
||||
receipts for this event. Due to the nature of private read
|
||||
receipts, this should only ever have the current user's ID.
|
||||
patternProperties:
|
||||
"^@": *receiptUserMap
|
||||
additionalProperties: false
|
||||
type:
|
||||
type: string
|
||||
enum: ["m.receipt"]
|
||||
enum: ["m.receipt", "m.receipt.private"]
|
||||
required: ["type", "content"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue