diff --git a/api/client-server/read_markers.yaml b/api/client-server/read_markers.yaml new file mode 100644 index 000000000..a74592c5f --- /dev/null +++ b/api/client-server/read_markers.yaml @@ -0,0 +1,79 @@ +# Copyright 2018 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Client-Server Read Marker API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/rooms/{roomId}/read_markers": + post: + summary: Set the position of the read marker for a room. + description: |- + Sets the position of the read marker for a given room, and optionally + the read receipt's location. + operationId: setReadMarker + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room ID to set the read marker in for the user. + required: true + x-example: "!somewhere:domain.com" + - in: body + name: body + description: The read marker and optional read receipt locations. + required: true + schema: + type: object + properties: + "m.fully_read": + type: string + description: |- + The event ID the read marker should be located at. The + event MUST belong to the room. + example: "$somewhere:domain.com" + "m.read": + type: string + description: |- + The event ID to set the read receipt location at. This is + equivalent to calling ``/receipt/m.read/$elsewhere:domain.com`` + and is provided here to save that extra call. + example: "$elsewhere:domain.com" + required: ['m.fully_read'] + responses: + 200: + description: |- + The read marker, and read receipt if provided, have been updated. + schema: + type: object + properties: {} + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - Read Markers diff --git a/changelogs/client_server/newsfragments/1635.feature b/changelogs/client_server/newsfragments/1635.feature new file mode 100644 index 000000000..3a5bb45fe --- /dev/null +++ b/changelogs/client_server/newsfragments/1635.feature @@ -0,0 +1 @@ +Add support for read markers. diff --git a/changelogs/client_server/newsfragments/1635.new b/changelogs/client_server/newsfragments/1635.new new file mode 100644 index 000000000..ec57e74bf --- /dev/null +++ b/changelogs/client_server/newsfragments/1635.new @@ -0,0 +1 @@ +POST ``/rooms/{roomId}/read_markers`` diff --git a/event-schemas/examples/m.fully_read b/event-schemas/examples/m.fully_read new file mode 100644 index 000000000..8278c6fa7 --- /dev/null +++ b/event-schemas/examples/m.fully_read @@ -0,0 +1,8 @@ +{ + "$ref": "core/event.json", + "type": "m.fully_read", + "room_id": "!somewhere:domain.com", + "content": { + "event_id": "$someplace:domain.com" + } +} diff --git a/event-schemas/schema/m.fully_read b/event-schemas/schema/m.fully_read new file mode 100644 index 000000000..51a1942f0 --- /dev/null +++ b/event-schemas/schema/m.fully_read @@ -0,0 +1,29 @@ +{ + "type": "object", + "title": "Read Marker Location Event", + "description": "The current location of the user's read marker in a room. This event appears in the user's room account data for the room the marker is applicable for.", + "allOf": [{ + "$ref": "core-event-schema/event.yaml" + }], + "properties": { + "content": { + "type": "object", + "properties": { + "event_id": { + "type": "string", + "description": "The event the user's read marker is located at in the room." + } + }, + "required": ["event_id"] + }, + "type": { + "type": "string", + "enum": ["m.fully_read"] + }, + "room_id": { + "type": "string", + "description": "The room ID the read marker applies to." + } + }, + "required": ["type", "room_id", "content"] +} diff --git a/specification/modules/account_data.rst b/specification/modules/account_data.rst index d0ed201a3..f0bf285f0 100644 --- a/specification/modules/account_data.rst +++ b/specification/modules/account_data.rst @@ -39,3 +39,10 @@ Client Behaviour ---------------- {{account_data_cs_http_api}} + + +Server Behaviour +---------------- + +Servers MUST reject clients from setting account data for event types that +the server manages. Currently, this only includes `m.fully_read`_. diff --git a/specification/modules/read_markers.rst b/specification/modules/read_markers.rst new file mode 100644 index 000000000..b2f77bc09 --- /dev/null +++ b/specification/modules/read_markers.rst @@ -0,0 +1,67 @@ +.. Copyright 2018 New Vector Ltd +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Fully read markers +================== + +.. _module:read-markers: + +The history for a given room may be split into three sections: messages the +user has read (or indicated they aren't interested in them), messages the user +might have read some but not others, and messages the user hasn't seen yet. +The "fully read marker" (also known as a "read marker") marks the last event +of the first section, whereas the user's read receipt marks the last event of +the second section. + +Events +------ +The user's fully read marker is kept as an event in the room's `account data`_. +The event may be read to determine the user's current fully read marker location +in the room, and just like other account data events the event will be pushed down +the event stream when updated. + +The fully read marker is kept under an ``m.fully_read`` event. If the event does +not exist on the user's account data, the fully read marker should be considered +to be the user's read receipt location. + +{{m_fully_read_event}} + +Client behaviour +---------------- +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. + +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 ``/receipts/m.read/$event:domain.com``. + +{{read_markers_cs_http_api}} + +Server behaviour +---------------- +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 ``/receipts/m.read/$event:domain.com``. + +Upon updating the ``m.fully_read`` event due to a request to ``/read_markers``, +the server MUST send the updated account data event through to the client via +the event stream (eg: ``/sync``), provided any applicable filters are also +satisfied. + + +.. _`account data`: #client-config diff --git a/specification/targets.yaml b/specification/targets.yaml index 56e9ec344..a2eb5cdda 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -45,6 +45,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/voip_events.rst - modules/typing_notifications.rst - modules/receipts.rst + - modules/read_markers.rst - modules/presence.rst - modules/content_repo.rst - modules/send_to_device.rst