From 53d7de2376b19cc9dabef6b0c0875b7c2719a1d2 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 14 Mar 2023 10:57:52 -0400 Subject: [PATCH] Define how clients process push rules (#1461) * Move Push Rules section out from Client Behaviour. * Clarify server vs. client behavior. * Remove references to unencrypted content. --- .../newsfragments/1461.clarification | 1 + content/client-server-api/modules/push.md | 164 ++++++++++-------- 2 files changed, 92 insertions(+), 73 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1461.clarification diff --git a/changelogs/client_server/newsfragments/1461.clarification b/changelogs/client_server/newsfragments/1461.clarification new file mode 100644 index 00000000..c205f380 --- /dev/null +++ b/changelogs/client_server/newsfragments/1461.clarification @@ -0,0 +1 @@ +Improve documentation of how clients use push rules. diff --git a/content/client-server-api/modules/push.md b/content/client-server-api/modules/push.md index 9c8d0adf..7667dd7a 100644 --- a/content/client-server-api/modules/push.md +++ b/content/client-server-api/modules/push.md @@ -85,58 +85,7 @@ Push Ruleset sender, a particular room, or by default. The push ruleset contains the entire set of scopes and rules. -#### Client behaviour - -Clients MUST configure a Pusher before they will receive push -notifications. There is a single API endpoint for this, as described -below. - -{{% http-api spec="client-server" api="pusher" %}} - -##### Listing Notifications - -A client can retrieve a list of events that it has been notified about. -This may be useful so that users can see a summary of what important -messages they have received. - -{{% http-api spec="client-server" api="notifications" %}} - -##### Receiving notifications - -Servers MUST include the number of unread notifications in a client's -`/sync` stream, and MUST update it as it changes. Notifications are -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. Which specific events are affected can vary depending -on whether a [threaded read receipt](#threaded-read-receipts) was used. -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 oldest-first 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). - -{{< added-in v="1.4" >}} When handling threaded read receipts, the server -is to partition the notification count to each thread (with the main timeline -being its own thread). To determine if an event is part of a thread the -server follows the [event relationship](#forming-relationships-between-events) -until it finds a thread root (as specified by the [threading module](#threading)), -however it is not recommended that the server traverse infinitely. Instead, -implementations are encouraged to do a maximum of 3 hops to find a thread -before deciding that the event does not belong to a thread. This is primarily -to ensure that future events, like `m.reaction`, are correctly considered -"part of" a given thread. - -##### Push Rules +#### Push Rules A push rule is a single rule that states under what *conditions* an event should be passed onto a push gateway and *how* the notification @@ -153,8 +102,8 @@ The different `kind`s of rule, in the order that they are checked, are: The highest priority rules are user-configured overrides. 1. **Content-specific rules (`content`).** - These configure behaviour for (unencrypted) messages that match certain - patterns. Content rules take one parameter: `pattern`, that gives the + These configure behaviour for messages that match certain patterns. Content + rules take one parameter: `pattern`, that gives the [glob-style pattern](/appendices#glob-style-matching) to match against. The match is performed case-insensitively, and must match any substring of the `content.body` property which starts and ends at a word boundary. A word @@ -188,7 +137,7 @@ rules match an event, the homeserver MUST NOT notify the Push Gateway for that event. Homeservers MUST NOT notify the Push Gateway for events that the user has sent themselves. -###### Actions +##### Actions All rules have an associated list of `actions`. An action affects if and how a notification is delivered for a matching event. The following @@ -246,7 +195,7 @@ they are represented as a dictionary with a key equal to their name and other keys as their parameters, e.g. `{ "set_tweak": "sound", "value": "default" }`. -###### Conditions +##### Conditions `override` and `underride` rules MAY have a list of 'conditions'. All conditions must hold true for an event in order for the rule to match. A @@ -346,10 +295,10 @@ For an example of this, see the default rule **`contains_display_name`** -This matches unencrypted messages where `content.body` contains the -owner's display name in that room. This is a separate rule because -display names may change and as such it would be hard to maintain a rule -that matched the user's display name. This condition has no parameters. +This matches messages where `content.body` contains the owner's display name in +that room. This is a separate condition because display names may change and as such +it would be hard to maintain a rule that matched the user's display name. This +condition has no parameters. **`room_member_count`** @@ -375,7 +324,7 @@ Parameters: to look up the power level required to send a notification type from the `notifications` object in the power level event content. -##### Predefined Rules +#### Predefined Rules Homeservers can specify "server-default rules". They operate at a lower priority than "user-defined rules", except for the `.m.rule.master` rule @@ -384,7 +333,7 @@ for all server-default rules MUST start with a dot (".") to identify them as "server-default". The following server-default rules are specified: -###### Default Override Rules +##### Default Override Rules **`.m.rule.master`** @@ -495,8 +444,8 @@ Definition: **`.m.rule.contains_display_name`** -Matches any message whose content is unencrypted and contains the user's -current display name in the room in which it was sent. +Matches any message whose content contains the user's current display name +in the room in which it was sent. Definition: @@ -525,8 +474,9 @@ Definition: **`.m.rule.roomnotif`** -Matches any message whose content is unencrypted and contains the text -`@room`, signifying the whole room should be notified of the event. +Matches any message from a sender with the proper power level whose content +contains the text `@room`, signifying the whole room should be notified of +the event. Definition: @@ -618,12 +568,12 @@ Definition: } ``` -###### Default Content Rules +##### Default Content Rules **`.m.rule.contains_user_name`** -Matches any message whose content is unencrypted and contains the local -part of the user's Matrix ID, separated by word boundaries. +Matches any message whose content contains the local part of the user's +Matrix ID, separated by word boundaries. Definition (as a `content` rule): @@ -646,7 +596,7 @@ Definition (as a `content` rule): } ``` -###### Default Underride Rules +##### Default Underride Rules **`.m.rule.call`** @@ -795,14 +745,14 @@ Definition: } ``` -##### Push Rules: API +#### Push Rules: API Clients can retrieve, add, modify and remove push rules globally or per-device using the APIs below. {{% http-api spec="client-server" api="pushrules" %}} -##### Push Rules: Events +#### Push Rules: Events When a user changes their push rules a `m.push_rules` event is sent to all clients in the `account_data` section of their next [`/sync`](#get_matrixclientv3sync) request. @@ -810,7 +760,7 @@ The content of the event is the current push rules for the user. {{% event event="m.push_rules" %}} -###### Examples +##### Examples To create a rule that suppresses notifications for the room with ID `!dj234r78wl45Gh4D:matrix.org`: @@ -861,8 +811,76 @@ than the room, sender and content rules): ] }' + +#### Client behaviour + +Clients MUST configure a Pusher before they will receive push +notifications. There is a single API endpoint for this, as described +below. + +{{% http-api spec="client-server" api="pusher" %}} + +##### Listing Notifications + +A client can retrieve a list of events that it has been notified about. +This may be useful so that users can see a summary of what important +messages they have received. + +{{% http-api spec="client-server" api="notifications" %}} + +##### Receiving notifications + +Servers MUST include the number of unread notifications in a client's +`/sync` stream, and MUST update it as it changes. Notifications are +determined by the push rules which apply to an event. + +For encrypted events, the homeserver has limited access to the event content +and properly processing push rules falls on the client. Clients should process +push rules for each incoming event *after decrypting* them. This may result in +needing to modify the number of unread notifications received from the homeserver. + +##### Marking notifications as read + +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. Which specific events are affected can vary depending +on whether a [threaded read receipt](#threaded-read-receipts) was used. +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 oldest-first 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). + +{{< added-in v="1.4" >}} When handling threaded read receipts, the server +is to partition the notification count to each thread (with the main timeline +being its own thread). To determine if an event is part of a thread the +server follows the [event relationship](#forming-relationships-between-events) +until it finds a thread root (as specified by the [threading module](#threading)), +however it is not recommended that the server traverse infinitely. Instead, +implementations are encouraged to do a maximum of 3 hops to find a thread +before deciding that the event does not belong to a thread. This is primarily +to ensure that future events, like `m.reaction`, are correctly considered +"part of" a given thread. + #### Server behaviour +When receiving a new event homeservers process push rules for each of the local +users in the room (excluding the sender). This may result in: + +* Generating a new number of unread notifications for the user. +* Making a request to the configured push gateway. + +The updated notification count from a new event MUST appear in the same `/sync` +response as the event itself. + #### Push Gateway behaviour ##### Recommendations for APNS