-
Notifications
You must be signed in to change notification settings - Fork 382
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add initial MSC for notfications for threads. * No longer depends on MSC3664. * Fix events in diagram. * Major simplification. * Add missing words. * Add a note about reactions. * Clarify homeserver behavior when processing push rules. * Link to a spec version instead of latest. Co-authored-by: Travis Ralston <travisr@matrix.org> * Update 3773-notifications-for-threads.md typoe * Clarify wording. * Update how homeservers are to partition threads. Co-authored-by: Travis Ralston <travisr@matrix.org> Co-authored-by: Matthew Hodgson <matthew@matrix.org>
- Loading branch information
1 parent
4e1b562
commit 9d80dcb
Showing
1 changed file
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
# MSC3773: Notifications for threads | ||
|
||
Since the unread notification count does not consider threads, a client is unable | ||
to separate the unread message counts into threads (as defined by | ||
[MSC3440](https://github.com/matrix-org/matrix-doc/pull/3440)) | ||
without iterating over every missing message. Without this, clients are unable to: | ||
|
||
* Let users know that a thread has new messages since they last read it. | ||
* Accurately display a count of unread messages in a room (or a thread). | ||
|
||
## Proposal | ||
|
||
### Modification to push rule processing | ||
|
||
When an event which is part of a thread matches a push rule which results in a | ||
`notify` action then the homeserver should partition the resulting notification | ||
count per-thread. (This is needed for the | ||
[proposed `/sync` changes](#unread-thread-notifications-in-the-sync-response)). | ||
|
||
It is recommended that at least 3 relations are traversed when attempting to | ||
find a thread, implementations should be careful to not infinitely recurse.[^1] | ||
|
||
Similar behavior should be applied for an event which results in `notify` action | ||
with a `highlight` tweak set. | ||
|
||
This MSC does not propose any changes to the payload sent to push gateways. | ||
|
||
### Unread thread notifications in the sync response | ||
|
||
Threaded clients can opt into receiving unread thread notifications by passing | ||
a new `unread_thread_notifications` parameter | ||
[as part of the `RoomEventFilter`](https://spec.matrix.org/v1.2/client-server-api/#filtering). | ||
(This is [similar to `lazy_load_members`](https://spec.matrix.org/v1.2/client-server-api/#lazy-loading-room-members), | ||
but only applies to the `/sync` endpoint.): | ||
|
||
* `unread_thread_notifications`: If `true`, enables partitioning of unread notification | ||
counts by thread. Defaults to false. | ||
|
||
If this flag is set to `true`, for each ["Joined Room" in the `/sync` response](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv3sync) | ||
a new field is added: | ||
|
||
* `unread_thread_notifications`: Counts of unread thread notifications for this | ||
room, an object which maps thread ID (the parent event ID) to | ||
`Unread Notification Counts`. | ||
|
||
Additionally, the `unread_notifications` dictionary is modified to only include | ||
unread notifications from events which are not part of a thread. | ||
|
||
An example of a joined room from a sync response: | ||
|
||
```json5 | ||
{ | ||
"account_data": { | ||
// ... | ||
}, | ||
"ephemeral": { | ||
// ... | ||
}, | ||
"state": { | ||
// ... | ||
}, | ||
"summary": { | ||
// ... | ||
}, | ||
"timeline": { | ||
"events": [ | ||
{ | ||
"event_id": "$143273582443PhrSn:example.org", | ||
// other fields ... | ||
}, | ||
{ | ||
"event_id": "$SGNxGPGUopcPBUoTTL:example.org", | ||
"m.relates_to": { | ||
"event_id": "$143273582443PhrSn:example.org", | ||
"rel_type": "m.thread" | ||
} | ||
// other fields ... | ||
} | ||
] | ||
}, | ||
"unread_notifications": { | ||
"highlight_count": 2, | ||
"notification_count": 18 | ||
}, | ||
"unread_thread_notifications": { | ||
"$143273582443PhrSn:example.org": { | ||
"highlight_count": 0, | ||
"notification_count": 1 | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Potential issues | ||
|
||
### Scalability | ||
|
||
Rooms with many unread threads could cause some 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. | ||
|
||
This is not dissimilar to rooms which are never read, however, as their unread | ||
counts are continually tracked and returned as part of the `/sync` response. | ||
|
||
### Clearing unread notifications | ||
|
||
This MSC does not attempt to modify how unread notifications (for a thread or | ||
otherwise) are cleared. It currently assumes the rules set forth by | ||
[read receipts](https://spec.matrix.org/v1.3/client-server-api/#receiving-notifications) | ||
still apply. This will cause some flakiness with unread notifications, as the current | ||
receipt infrastructure assumes that a room's timeline is linear, which is no | ||
longer true. | ||
|
||
[MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) is a | ||
potential solution for this. | ||
|
||
## Alternatives | ||
|
||
### Using push rules | ||
|
||
It might seem that a new push rule `action` (or `tweak`) should be used to control | ||
the behavior of whether an event generates a notification for a thread or the | ||
room itself. There are issues with either approach though: | ||
|
||
A new `action` (e.g. `notify_thread`) would mean that additional logic would | ||
need to be defined and added for events which aren't part of a thread but attempt | ||
to use this action. It also conflicts with [MSC3768](https://github.com/matrix-org/matrix-spec-proposals/pull/3768), | ||
which attempts to define another `action` which should also work fine for threads. | ||
|
||
A new `tweak` (e.g. `threaded`) was discarded as an option since there is no need to | ||
pass this through to the push server, which is at odds with the current `tweaks` | ||
mechanism. | ||
|
||
Regardless, the main issue with using push rules is that it becomes necessary to | ||
define rules which match threaded events. Whenever adding a new rule, matching rules | ||
would need to be added, but as a thread-specific version. | ||
|
||
## Security considerations | ||
|
||
N/A | ||
|
||
## Unstable prefix | ||
|
||
While this feature is in development the following unstable prefixes should be used: | ||
|
||
* `unread_thread_notifications` --> `org.matrix.msc3773.unread_thread_notifications` | ||
|
||
To detect server support, clients can either rely on the spec version (when stable) | ||
or the presence of a `org.matrix.msc3773` flag in `unstable_features` on `/versions`. | ||
|
||
## Dependencies | ||
|
||
N/A | ||
|
||
[^1]: Three relations is relatively arbitrary, but is meant to cover an edit or | ||
reaction to a thread (to an event with no relations, i.e. the root of a thread): | ||
`A<--[m.thread]--B<--[m.annotation]--C`. | ||
With an additional leftover for future improvements. This is considered reasonable | ||
since threads cannot fork, edits cannot modify relation information, and generally | ||
annotations to annotations are ignored by user interfaces. |