From ccd7bb32d5bfb76206e97e2e8e659dcb54e17434 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 27 Sep 2016 12:17:05 +0100 Subject: [PATCH 1/3] Specification for direct-to-device messages --- api/client-server/sync.yaml | 6 + api/client-server/to_device.yaml | 89 +++++++++++++ changelogs/client_server.rst | 2 + specification/modules/store_and_forward.rst | 140 ++++++++++++++++++++ specification/server_server_api.rst | 24 ++++ specification/targets.yaml | 1 + 6 files changed, 262 insertions(+) create mode 100644 api/client-server/to_device.yaml create mode 100644 specification/modules/store_and_forward.rst diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 8bfdd48a..2f77345d 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -236,6 +236,12 @@ paths: The global private data created by this user. allOf: - $ref: "definitions/event_batch.yaml" + to_device: + title: ToDevice + type: object + description: |- + Information on the store-and-forward messages for the client device, as defined in + |store_and_forward_sync|_. examples: application/json: |- { diff --git a/api/client-server/to_device.yaml b/api/client-server/to_device.yaml new file mode 100644 index 00000000..589ec0d7 --- /dev/null +++ b/api/client-server/to_device.yaml @@ -0,0 +1,89 @@ +# Copyright 2016 OpenMarket 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 Send-to-device 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: + "/sendToDevice/{eventType}/{txnId}": + put: + summary: Send to-device event to a given set of devices. + description: |- + This endpoint is used to send store-and-forward events to a set of + client devices. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: eventType + description: The type of event to send. + required: true + x-example: "m.new_device" + - in: path + name: txnId + type: string + description: |- + The transaction ID for this event. Clients should generate an + ID unique across requests with the same access token; it will be + used by the server to ensure idempotency of requests. + required: true + x-example: "35" + - in: body + name: body + required: true + schema: + type: object + title: body + properties: + messages: + type: object + description: |- + The messages to send. A map from user ID, to a map from + device ID to message body. The device ID may also be `*`, + meaning all known devices for the user. + additionalProperties: + type: object + additionalProperties: + type: object + title: EventContent + description: Message content + example: { + "@alice:example.com": { + "tLLbenaag": { + "example_content_key": "value" + } + } + } + responses: + 200: + description: + The message was successfully sent. + examples: + application/json: |- + {} + tags: + - Store-and-forward messaging diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index d7384e31..bd75fb28 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,6 +35,8 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). + - Add "Store-and-Forward messaging" module + (`#386 `_). r0.2.0 ====== diff --git a/specification/modules/store_and_forward.rst b/specification/modules/store_and_forward.rst new file mode 100644 index 00000000..0f41412d --- /dev/null +++ b/specification/modules/store_and_forward.rst @@ -0,0 +1,140 @@ +.. Copyright 2016 OpenMarket 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. + +Store-and-Forward messaging +=========================== + +.. _module:to_device: + +This module provides a means by which clients can exchange signalling messages +without them being stored permanently as part of a shared communication +history. A message is delivered exactly once to each client device. + +Client behaviour +---------------- +To send a message to other devices, a client should call |/sendToDevice|_. +Only one message can be sent to each device per transaction, and they must all +have the same event type. The device ID in the request body can be set to ``*`` +to request that the message be sent to all known devices. + +If there are store-and-forward messages waiting for a client, they will be +returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should +inspect the ``type`` of each returned event, and ignore any they do not +understand. + +Server behaviour +---------------- +Servers should store pending messages for local users until they are +successfully delivered to the destination device. When a client calls |/sync|_ +with an access token which corresponds to a device with pending messages, the +server should list the pending messages, in order of arrival, in the response +body. + +When the client calls ``/sync`` again with the ``next_batch`` token from the +first response, the server should infer that any store-and-forward messages in +that response have been delivered successfully, and delete them from the store. + +If there is a large queue of store-and-forward messages, the server should +limit the number sent in each ``/sync`` response. 100 messages is recommended +as a reasonable limit. + +If the client sends messages to users on remote domains, those messages should +be sent on to the remote servers via +`federation`_. + +.. _`federation`: ../server_server/latest.html#store-and-forward-messages + +.. TODO-spec: + + * Is a server allowed to delete undelivered messages? After how long? What + about if the device is deleted? + + * If the destination HS doesn't support the ``m.direct_to_device`` EDU, it + will just get dumped. Should we indicate that to the client? + + +Protocol definitions +-------------------- + +{{to_device_cs_http_api}} + +.. TODO-spec: + + * What should a server do if the user id or device id is unknown? Presumably + it shouldn't reject the request outright, because some of the destinations + may be valid. Should we add something to the response? + +.. anchor for link from /sync api spec +.. |store_and_forward_sync| replace:: Store-and-Forward messaging +.. _store_and_forward_sync: + +Extensions to /sync +~~~~~~~~~~~~~~~~~~~ + +This module adds the following properties to the |/sync|_ response: + +.. todo: generate this from a swagger definition? + +========= ========= ======================================================= +Parameter Type Description +========= ========= ======================================================= +to_device ToDevice Optional. Information on the store-and-forward messages + for the client device. +========= ========= ======================================================= + +``ToDevice`` + +========= ========= ============================================= +Parameter Type Description +========= ========= ============================================= +events [Event] List of store-and-forward messages +========= ========= ============================================= + +``Event`` + +================ ============ ================================================== +Parameter Type Description +================ ============ ================================================== +content EventContent The content of this event. The fields in this + object will vary depending on the type of event. +sender string The Matrix user ID of the user who sent this + event. +type string The type of event. +================ ============ ================================================== + + +Example response: + +.. code:: json + + { + "next_batch": "s72595_4483_1934", + "rooms": {"leave": {}, "join": {}, "invite": {}}, + "to_device": { + "events": [ + { + "sender": "@alice:example.com", + "type": "m.new_device", + "content": { + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + } + } + ] + } + } + + +.. |/sendToDevice| replace:: ``/sendToDevice`` +.. _/sendToDevice: #put-matrix-client-%CLIENT_MAJOR_VERSION%-sendtodevice-eventtype-txnid diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 5c8a456a..1d4b7249 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -974,3 +974,27 @@ The list of join candidates is a list of server names that are likely to hold the given room; these are servers that the requesting server may wish to use as resident servers as part of the remote join handshake. This list may or may not include the server answering the query. + +Store-and-forward messages +-------------------------- + +.. TODO: add modules to the federation spec and make this a module + +The server API for store-and-forward messaging is based on the following +EDU. There are no PDUs or Federation Queries involved. + +Each store-and-forward message should be sent to the destination server using +the following EDU:: + + EDU type: m.direct_to_device + + Content keys: + sender: user ID of the sender + + type: event type for the message + + message_id: unique id for the message: used for idempotence + + messages: The messages to send. A map from user ID, to a map from device ID + to message body. The device ID may also be *, meaning all known devices + for the user. diff --git a/specification/targets.yaml b/specification/targets.yaml index 6cbfa917..ca2e0044 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -41,6 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/receipts.rst - modules/presence.rst - modules/content_repo.rst + - modules/store_and_forward.rst - modules/end_to_end_encryption.rst - modules/history_visibility.rst - modules/push.rst From ebaaa7e3b335f436681ecbd7c2cfbde047292803 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 29 Sep 2016 13:18:45 +0100 Subject: [PATCH 2/3] Review feedback * store-and-forward -> send-to-device * describe motivation * device ids are 10 capital chars * etc --- api/client-server/sync.yaml | 4 +-- api/client-server/to_device.yaml | 8 +++--- specification/client_server_api.rst | 3 +++ ...ore_and_forward.rst => send_to_device.rst} | 26 ++++++++++++------- specification/server_server_api.rst | 8 +++--- specification/targets.yaml | 2 +- 6 files changed, 30 insertions(+), 21 deletions(-) rename specification/modules/{store_and_forward.rst => send_to_device.rst} (83%) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 2f77345d..66f7d935 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -240,8 +240,8 @@ paths: title: ToDevice type: object description: |- - Information on the store-and-forward messages for the client device, as defined in - |store_and_forward_sync|_. + Information on the send-to-device messages for the client + device, as defined in |send_to_device_sync|_. examples: application/json: |- { diff --git a/api/client-server/to_device.yaml b/api/client-server/to_device.yaml index 589ec0d7..16af1182 100644 --- a/api/client-server/to_device.yaml +++ b/api/client-server/to_device.yaml @@ -30,9 +30,9 @@ securityDefinitions: paths: "/sendToDevice/{eventType}/{txnId}": put: - summary: Send to-device event to a given set of devices. + summary: Send an event to a given set of devices. description: |- - This endpoint is used to send store-and-forward events to a set of + This endpoint is used to send send-to-device events to a set of client devices. security: - accessToken: [] @@ -73,7 +73,7 @@ paths: description: Message content example: { "@alice:example.com": { - "tLLbenaag": { + "TLLBEANAAG": { "example_content_key": "value" } } @@ -86,4 +86,4 @@ paths: application/json: |- {} tags: - - Store-and-forward messaging + - Send-to-Device messaging diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a74129b5..6eb24823 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1258,6 +1258,9 @@ have to wait in milliseconds before they can try again. .. |/rooms//state| replace:: ``/rooms//state`` .. _/rooms//state: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state +.. |/rooms//send| replace:: ``/rooms//send`` +.. _/rooms//send: #put-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-send-eventtype-txnid + .. |/rooms//invite| replace:: ``/rooms//invite`` .. _/rooms//invite: #post-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-invite diff --git a/specification/modules/store_and_forward.rst b/specification/modules/send_to_device.rst similarity index 83% rename from specification/modules/store_and_forward.rst rename to specification/modules/send_to_device.rst index 0f41412d..dd85a992 100644 --- a/specification/modules/store_and_forward.rst +++ b/specification/modules/send_to_device.rst @@ -12,8 +12,8 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -Store-and-Forward messaging -=========================== +Send-to-Device messaging +======================== .. _module:to_device: @@ -21,6 +21,12 @@ This module provides a means by which clients can exchange signalling messages without them being stored permanently as part of a shared communication history. A message is delivered exactly once to each client device. +The primary motivation for this API is exchanging data that is meaningless or +undesirable to persist in the room DAG - for example, one-time authentication +tokens or key data. It is not intended for conversational data, which should be +sent using the normal |/rooms//send|_ API for consistency throughout +Matrix. + Client behaviour ---------------- To send a message to other devices, a client should call |/sendToDevice|_. @@ -28,7 +34,7 @@ Only one message can be sent to each device per transaction, and they must all have the same event type. The device ID in the request body can be set to ``*`` to request that the message be sent to all known devices. -If there are store-and-forward messages waiting for a client, they will be +If there are send-to-device messages waiting for a client, they will be returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should inspect the ``type`` of each returned event, and ignore any they do not understand. @@ -42,10 +48,10 @@ server should list the pending messages, in order of arrival, in the response body. When the client calls ``/sync`` again with the ``next_batch`` token from the -first response, the server should infer that any store-and-forward messages in +first response, the server should infer that any send-to-device messages in that response have been delivered successfully, and delete them from the store. -If there is a large queue of store-and-forward messages, the server should +If there is a large queue of send-to-device messages, the server should limit the number sent in each ``/sync`` response. 100 messages is recommended as a reasonable limit. @@ -53,7 +59,7 @@ If the client sends messages to users on remote domains, those messages should be sent on to the remote servers via `federation`_. -.. _`federation`: ../server_server/latest.html#store-and-forward-messages +.. _`federation`: ../server_server/latest.html#send-to-device-messages .. TODO-spec: @@ -76,8 +82,8 @@ Protocol definitions may be valid. Should we add something to the response? .. anchor for link from /sync api spec -.. |store_and_forward_sync| replace:: Store-and-Forward messaging -.. _store_and_forward_sync: +.. |send_to_device_sync| replace:: Send-to-Device messaging +.. _send_to_device_sync: Extensions to /sync ~~~~~~~~~~~~~~~~~~~ @@ -89,7 +95,7 @@ This module adds the following properties to the |/sync|_ response: ========= ========= ======================================================= Parameter Type Description ========= ========= ======================================================= -to_device ToDevice Optional. Information on the store-and-forward messages +to_device ToDevice Optional. Information on the send-to-device messages for the client device. ========= ========= ======================================================= @@ -98,7 +104,7 @@ to_device ToDevice Optional. Information on the store-and-forward messages ========= ========= ============================================= Parameter Type Description ========= ========= ============================================= -events [Event] List of store-and-forward messages +events [Event] List of send-to-device messages ========= ========= ============================================= ``Event`` diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 1d4b7249..5d7f2b17 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -975,15 +975,15 @@ the given room; these are servers that the requesting server may wish to use as resident servers as part of the remote join handshake. This list may or may not include the server answering the query. -Store-and-forward messages --------------------------- +Send-to-device messaging +------------------------ .. TODO: add modules to the federation spec and make this a module -The server API for store-and-forward messaging is based on the following +The server API for send-to-device messaging is based on the following EDU. There are no PDUs or Federation Queries involved. -Each store-and-forward message should be sent to the destination server using +Each send-to-device message should be sent to the destination server using the following EDU:: EDU type: m.direct_to_device diff --git a/specification/targets.yaml b/specification/targets.yaml index ca2e0044..129cfe11 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -41,7 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/receipts.rst - modules/presence.rst - modules/content_repo.rst - - modules/store_and_forward.rst + - modules/send_to_device.rst - modules/end_to_end_encryption.rst - modules/history_visibility.rst - modules/push.rst From 4f1c2f23ee2c76b1b5995f92da7a0198501752ee Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 29 Sep 2016 13:21:46 +0100 Subject: [PATCH 3/3] Changelog fix store-and-forward -> send-to-device --- changelogs/client_server.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index bd75fb28..10a6876a 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,7 +35,7 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add "Store-and-Forward messaging" module + - Add "Send-to-Device messaging" module (`#386 `_). r0.2.0