diff --git a/api/client-server/account-data.yaml b/api/client-server/account-data.yaml index 76b2b156..c468f1c0 100644 --- a/api/client-server/account-data.yaml +++ b/api/client-server/account-data.yaml @@ -67,6 +67,17 @@ paths: 200: description: The account_data was successfully added. + 405: + description: + The account data event type cannot be set here. This generally indicates + that another API is available for managing the data contained in the event. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_UNKNOWN", + "error": "Cannot set m.fully_read through this API. Use /rooms/{roomId}/read_markers" + } tags: - User data "/user/{userId}/rooms/{roomId}/account_data/{type}": @@ -116,5 +127,16 @@ paths: 200: description: The account_data was successfully added. + 405: + description: + The account data event type cannot be set here. This generally indicates + that another API is available for managing the data contained in the event. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_UNKNOWN", + "error": "Cannot set m.fully_read through this API. Use /rooms/{roomId}/read_markers" + } tags: - User data diff --git a/api/client-server/read_markers.yaml b/api/client-server/read_markers.yaml new file mode 100644 index 00000000..a74592c5 --- /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/event-schemas/examples/m.fully_read b/event-schemas/examples/m.fully_read new file mode 100644 index 00000000..8278c6fa --- /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 00000000..51a1942f --- /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/read_markers.rst b/specification/modules/read_markers.rst new file mode 100644 index 00000000..0a5578d6 --- /dev/null +++ b/specification/modules/read_markers.rst @@ -0,0 +1,70 @@ +.. 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. + +Read Markers +============ + +.. _module:read-markers: + +A "read marker" is a bookmark in the room's history where the user has last +read a message. Read receipts cover the most recently read message, and have +slightly different semantics where they are to be sent when the user has most +likely seen the message, but not necessarily read it. A read marker tracks +the user's last read message, therefore making the messages between the read +marker and read receipt "potentially read" and messages before the read marker +as "read". Messages after the read receipt should be considered as "unread", +therefore the read marker should always be earlier or equal to the location of +the read receipt. + +Events +------ +The user's read marker is kept as an event in the room's `account data`_. The +event may be read to determine the user's current 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 read marker is kept under an ``m.fully_read`` event. If the event does +not exist on the user's account data, the read marker should be considered +to be the user's read receipt location. + +{{m_fully_read_event}} + +Client behaviour +---------------- +The client cannot update 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 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 56e9ec34..a2eb5cdd 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