-
Notifications
You must be signed in to change notification settings - Fork 399
MSC3771: Read receipts for threads #3771
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
Changes from 1 commit
d330ba9
42d7daf
4c5382d
b5dac99
9445049
0e42ec3
e74c989
65fa009
1f0d6dd
03ac0e0
e3e677a
5540252
bbdb23e
2678f3c
ea77632
1c60533
347d332
5d73531
ef736e4
de7ba49
e1ab8e5
6e71034
2b857b7
d423542
ecbd6c4
1a5b5ae
7471923
b171a31
668c9de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
# MSC3771: Read receipts for threads | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Currently, each room has a single read receipt per user. This is used to sync the | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
read status of a room across clients and calculate the number of unread messages. | ||
|
||
Unfortunately a client displaying threads may show a subset of a room's messages | ||
at a time, causing the read receipt to be misleading. | ||
|
||
This might better be described by an example. Given a room with the following | ||
DAG of events (note that the dotted lines are a thread relation, as specified by | ||
[MSC3440](https://github.com/matrix-org/matrix-doc/pull/3440)): | ||
|
||
```mermaid | ||
flowchart RL | ||
F-->E | ||
E-->D | ||
D-->C | ||
C-->B | ||
B-->A | ||
D-.->A | ||
F-.->A | ||
``` | ||
|
||
A client might interpret this as: | ||
|
||
```mermaid | ||
flowchart RL | ||
subgraph Main timeline | ||
C-->B | ||
B-->A | ||
F-->C | ||
end | ||
subgraph Thread timeline | ||
D-->A | ||
E-->D | ||
end | ||
|
||
style A fill:cyan,stroke:#333,stroke-width:2px | ||
style E fill:orange,stroke:#333,stroke-width:2px | ||
``` | ||
|
||
While viewing the "main" timeline of the room, a client might move the read | ||
receipt from event `A` to event `E` without ever showing events `D` and `F`. The | ||
user then reads the thread, the client has no way to mark `F` as read. | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Proposal | ||
|
||
This MSC proposes adding a new receipt type of `m.read.thread.private` is to be | ||
added. This receipt type is used for clients to sync the read status of each | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
thread in a room. | ||
|
||
The `/receipt` endpoint gains a new optional path part and becomes: | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
`POST /_matrix/client/v3/rooms/{roomId}/receipt/{receiptType}/{eventId}/{context}` | ||
|
||
The `context` contains the thread that the read receipts belongs to (i.e. it should | ||
match the `event_id` contained within the `m.relates_to` of the event represented | ||
by `eventId`). This updates the unique tuple for receipts from | ||
`(room ID, user ID, receipt type)` to `(room ID, user ID, receipt type, context)`. | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
For backwards compatibility, a missing `context` is equivalent to an empty context. | ||
|
||
Given a threaded message: | ||
|
||
```json | ||
{ | ||
"event_id": "$thread_reply", | ||
"room_id": "!room:example.org", | ||
"content": { | ||
"m.relates_to": { | ||
"rel_type": "m.thread", | ||
"event_id": "$thread_root" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
A client could mark this as read by sending a request: | ||
|
||
``` | ||
POST /_matrix/client/r0/rooms/!room:example.org/receipt/m.read.thread.private/$thread_reply/$thread_root | ||
|
||
{} | ||
``` | ||
|
||
Similarly to the hidden read receipts from [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285), | ||
homeservers are not to send the receipt to any other users except the sender nor | ||
over federation. | ||
|
||
## Potential issues | ||
|
||
For long-lived rooms or rooms with many threads there could be a significant number | ||
of receipts. This has a few downsides: | ||
|
||
* The size of the `/sync` response would increase without bound. | ||
* The effort to generate and process the receipts for each room would increase | ||
without bound. | ||
dbkr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a plan for this? I don't think this is a viable situation long-term, though happy enough to punt it for now. (might be worth looping in people thinking about sliding sync?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't have a long-term plan for this, no. I'm unsure how much of a concern this really is -- it would depend how often folks sending threaded read receipts, although "without bound" might have been a bit of hyperbole. I think from this we'll end up processing more receipts, but they'll be over smaller chunks of events, so I hope the actual effort isn't too much worse. |
||
|
||
Due to both of the above, this proposal is limited to a *private* read receipt for | ||
threads. This limits the impact to a user's own read receipts for threads, but | ||
does not completely solve the issue. | ||
|
||
[MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285) suggests | ||
that the `/read_markers` endpoint should become a generic bulk receipt endpoint. | ||
This is not compatible with the additional `context` parameter in this MSC. | ||
|
||
## Alternatives | ||
|
||
Instead of adding the thread ID as a new path part, it could be added to the body | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
of the receipt. There may be a small backwards compatibility benefit to this, but | ||
it seems clearer to put it as part of the URL. | ||
|
||
Similarly, instead of adding a new receipt type, the read status of each thread in | ||
a room could be added to the body of the `m.read.private` receipt. This could | ||
cause data integrity issues if multiple clients attempt to update the receipt | ||
without first reading it. | ||
|
||
Instead of adding the thread ID as a new path part, it could be encoded as a suffix | ||
on the receipt, e.g. `m.thread.read.private-$abcd`. This has the benefit of not | ||
changing the current receipt mechanisms, but seems sub-par and requires additional | ||
parsing of opaque identifiers. | ||
|
||
## Security considerations | ||
|
||
There is potential for abuse by allowing clients to specify a unique `context`. | ||
A mitigation could be to ensure that it is the related event of the thread, ensuring | ||
that each thread only has a single context. | ||
|
||
## Future extensions | ||
|
||
Future extensions will tackle how the thread read receipts impact notification counts. | ||
|
||
## Unstable prefix | ||
|
||
During implementation the receipt type shall be `org.matrix.mscXXXX`. | ||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To avoid receipts that will never be updated, after stabilization, homeservers are | ||
expected to reject the unstable receipt type and purge all receipts using the | ||
unstable receipt type. | ||
|
||
To detect server support, clients can either rely on the spec version (when stable) | ||
or the presence of a `org.matrix.msc3771` flag in `unstable_features` on `/versions`. | ||
|
||
## Dependencies | ||
|
||
This MSC depends on the following MSCs, which at the time of writing have not yet | ||
been accepted into the spec: | ||
|
||
* [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285): Hidden read receipts | ||
|
||
As well as the following MSCs, which have been accepted into the spec, but have | ||
yet to be released: | ||
|
||
* [MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674): Event Relationships | ||
* [MSC3440](https://github.com/matrix-org/matrix-spec-proposals/pull/3440): Threading via `m.thread` relation |
Uh oh!
There was an error while loading. Please reload this page.