From 58c28598af33ef2a66439ac9758d3aae39655874 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 19 Mar 2015 14:21:08 +0100 Subject: [PATCH] lots of fixes based on kegan's review of https://github.com/matrix-org/matrix-doc/pull/13 --- drafts/definitions.rst | 4 +- drafts/general_api.rst | 5 +- specification/00_basis.rst | 71 ++++++++++++++------------ specification/10_client_server_api.rst | 53 ++++++++++--------- specification/20_events.rst | 38 +++++++++++--- specification/42_push_overview.rst | 7 ++- specification/43_push_cs_api.rst | 14 +++-- specification/44_push_push_gw_api.rst | 5 +- 8 files changed, 112 insertions(+), 85 deletions(-) diff --git a/drafts/definitions.rst b/drafts/definitions.rst index 4db39222..cfb56857 100644 --- a/drafts/definitions.rst +++ b/drafts/definitions.rst @@ -5,7 +5,7 @@ Definitions # *Event* -- A JSON object that represents a piece of information to be distributed to the the room. The object includes a payload and metadata, -including a `type` used to indicate what the payload is for and how to process +including a ``type`` used to indicate what the payload is for and how to process them. It also includes one or more references to previous events. # *Event graph* -- Events and their references to previous events form a @@ -13,7 +13,7 @@ directed acyclic graph. All events must be a descendant of the first event in a room, except for a few special circumstances. # *State event* -- A state event is an event that has a non-null string valued -`state_key` field. It may also include a `prev_state` key referencing exactly +`state_key` field. It may also include a ``prev_state`` key referencing exactly one state event with the same type and state key, in the same event graph. # *State tree* -- A state tree is a tree formed by a collection of state events diff --git a/drafts/general_api.rst b/drafts/general_api.rst index 6c87c0f6..ea24c135 100644 --- a/drafts/general_api.rst +++ b/drafts/general_api.rst @@ -811,8 +811,9 @@ Notes: Presence API ``[Draft]`` ------------------------ -FIXME: this seems to be ignoring activity timers entirely, which were present on -the planning etherpad and are present in the actual HTTP API. Needs attention. +.. FIXME + this seems to be ignoring activity timers entirely, which were present on + the planning etherpad and are present in the actual HTTP API. Needs attention. The goals of presence are to: diff --git a/specification/00_basis.rst b/specification/00_basis.rst index 37d1b9ef..5faacc0d 100644 --- a/specification/00_basis.rst +++ b/specification/00_basis.rst @@ -13,11 +13,11 @@ Table of Contents Introduction ============ -Matrix is a set of open APIs for open-federated Instant Messaging, VoIP and -Internet of Things communication, designed to create and support a new global -real-time communication ecosystem. The intention is to provide an open -decentralised pubsub fabric for the internet for securely persisting and -publishing/subscribing JSON objects. +Matrix is a set of open APIs for open-federated Instant Messaging (IM), Voice +over IP (VoIP) and Internet of Things (IoT) communication, designed to create +and support a new global real-time communication ecosystem. The intention is to +provide an open decentralised pubsub layer for the internet for securely +persisting and publishing/subscribing JSON objects. This specification is the ongoing result of standardising the APIs used by the various components of the Matrix ecosystem to communicate with one another. @@ -101,23 +101,25 @@ Architecture ------------ Matrix defines APIs for synchronising extensible JSON objects known as -`events` between compatible clients, servers and services. Clients are +``events`` between compatible clients, servers and services. Clients are typically messaging/VoIP applications or IoT devices/hubs and communicate by -synchronising communication history with their `homeserver` using the -`Client-Server API`. Each homeserver stores the communication history and +synchronising communication history with their ``homeserver`` using the +``Client-Server API``. Each homeserver stores the communication history and account information for all of its clients, and shares data with the wider Matrix ecosystem by synchronising communication history with other homeservers and their clients. Clients typically communicate with each other by emitting events in the -context of a virtual `room`. Room data is replicated across *all of the +context of a virtual ``room``. Room data is replicated across *all of the homeservers* whose users are participating in a given room. As such, *no single homeserver has control or ownership over a given room*. Homeservers model communication history as a partially ordered graph of events known as -the room's `event graph`, which is synchronised with eventual consistency -between the participating servers using the Server-Server API. Matrix optimises -for the the Availability and Partitioned properties of CAP theorem at the -expense of Consistency. +the room's ``event graph``, which is synchronised with eventual consistency +between the participating servers using the ``Server-Server API``. This process +of synchronising shared conversation history between homeservers run by +different parties is called ``Federation``. Matrix optimises for the the +Availability and Partitioned properties of CAP theorem at +the expense of Consistency. For example, for client A to send a message to client B, client A performs an HTTP PUT of the required JSON event on its homeserver (HS) using the @@ -144,6 +146,7 @@ a long-lived GET request. | |<--------( HTTPS )----------| | +------------------+ Server-Server API +------------------+ History Synchronisation + (Federation) Users @@ -179,11 +182,11 @@ Event Graphs ~~~~~~~~~~~~ Events exchanged in the context of a room are stored in a directed acyclic graph -(DAG) called an `event graph`. The partial ordering of this graph gives the +(DAG) called an ``event graph``. The partial ordering of this graph gives the chronological ordering of events within the room. Each event in the graph has a -list of zero or more `parent` events, which refer to any preceeding events which -have no chronological successor from the perspective of the homeserver which -created the event. +list of zero or more ``parent`` events, which refer to any preceeding events +which have no chronological successor from the perspective of the homeserver +which created the event. Typically an event has a single parent: the most recent message in the room at the point it was sent. However, homeservers may legitimately race with each @@ -192,10 +195,10 @@ successors. The next event added to the graph thus will have multiple parents. Every event graph has a single root event with no parent. To order and ease chronological comparison between the events within the graph, -homeservers maintain a `depth` metadata field on each event. An event's `depth` -is a positive integer that is strictly greater than the depths of any of its -parents. The root event should have a depth of 1. Thus if one event is before -another, then it must have a strictly smaller depth. +homeservers maintain a ``depth`` metadata field on each event. An event's +``depth`` is a positive integer that is strictly greater than the depths of any +of its parents. The root event should have a depth of 1. Thus if one event is +before another, then it must have a strictly smaller depth. Room structure ~~~~~~~~~~~~~~ @@ -229,7 +232,7 @@ the room ``!qporfwt:matrix.org``:: | matrix.org | | domain.com | +------------------+ +------------------+ | ^ - | [HTTP POST] | + | [HTTP PUT] | | Room ID: !qporfwt:matrix.org | | Event type: m.room.message | | Content: { JSON object } | @@ -357,9 +360,11 @@ this user's presence through a presence list or by sharing membership of a room. The last_active specifics should be moved to the detailed presence event section Last activity is tracked by the server maintaining a timestamp of the last time -it saw a pro-active event from the user; either sending a message to a room, -coming online or back from idle, etc. This timestamp is presented via a key -called ``last_active_ago``, which gives the relative number of milliseconds +it saw a pro-active event from the user. Any event which could be triggered by a +human using the application is considered pro-active (e.g. sending an event to a +room). An example of a non-proactive client activity would be a client setting +'idle' presence status, or polling for events. This timestamp is presented via a +key called ``last_active_ago``, which gives the relative number of milliseconds since the message is generated/emitted that the user was last seen active. N.B. in v1 API, status/online/idle state are muxed into a single 'presence' field on the m.presence event. @@ -382,10 +387,10 @@ Users may publish arbitrary key/value data associated with their account - such as a human readable ``display name``, a profile photo URL, contact information (email address, phone nubers, website URLs etc). -Profile data is typed using namespaced keys for interoperability, much like -events - e.g. ``m.profile.display_name``. +In Client-Server API v2, profile data is typed using namespaced keys for +interoperability, much like events - e.g. ``m.profile.display_name``. -..TODO +.. TODO Actually specify the different types of data - e.g. what format are display names allowed to be? @@ -396,7 +401,7 @@ Users may also store arbitrary private key/value data in their account - such as client preferences, or server configuration settings which lack any other dedicated API. The API is symmetrical to managing Profile data. -..TODO +.. TODO Would it really be overengineered to use the same API for both profile & private user data, but with different ACLs? @@ -436,15 +441,13 @@ response". This is a JSON object which looks like:: The ``error`` string will be a human-readable error message, usually a sentence explaining what went wrong. The ``errcode`` string will be a unique string which can be used to handle an error message e.g. ``M_FORBIDDEN``. These error -codes should have their namespace first in ALL CAPS, followed by a single _. -For example, if there was a custom namespace ``com.mydomain.here``, and a +codes should have their namespace first in ALL CAPS, followed by a single _ to +ease seperating the namespace from the error code.. For example, if there was a +custom namespace ``com.mydomain.here``, and a ``FORBIDDEN`` code, the error code should look like ``COM.MYDOMAIN.HERE_FORBIDDEN``. There may be additional keys depending on the error, but the keys ``error`` and ``errcode`` MUST always be present. -..TODO - Why the weird mix of underscore and dots? - Some standard error codes are below: :``M_FORBIDDEN``: diff --git a/specification/10_client_server_api.rst b/specification/10_client_server_api.rst index ebea7bb9..5129af16 100644 --- a/specification/10_client_server_api.rst +++ b/specification/10_client_server_api.rst @@ -20,10 +20,10 @@ Pagination Querying large datasets in Matrix always uses the same pagination API pattern to to give clients a consistent way of selecting subsets of a potentially changing -dataset. Requests pass in `from`, `to` and `limit` parameters which describe -where to read from the stream. `from` and `to` are opaque textual 'stream +dataset. Requests pass in ``from``, ``to`` and ``limit`` parameters which describe +where to read from the stream. ``from`` and ``to`` are opaque textual 'stream tokens' which describe positions in the dataset. The response returns new -`start` and `end` stream token values which can then be passed to subsequent +``start`` and ``end`` stream token values which can then be passed to subsequent requests to continue pagination. Pagination Request Query Parameters @@ -35,13 +35,13 @@ Query parameters: to: $streamtoken - The opaque token to end streaming at. Typically, clients will not know the item of data to end at, so this will usually be - START or END. + omitted. limit: integer - An integer representing the maximum number of items to return. -'START' and 'END' are magic token values which specify the start and end of the -dataset respectively. +'START' and 'END' are placeholder values used in these examples to describe the +start and end of the dataset respectively. Unless specified, the default pagination parameters are from=START, to=END, without a limit set. This allows you to hit an API like @@ -96,11 +96,6 @@ Where $streamtoken is an opaque token which can be used in another query to get the next set of results. The "start" and "end" keys can only be omitted if the complete dataset is provided in "chunk". -If the client wants earlier results, they should use from=$start_streamtoken, -to=START. Likewise, if the client wants later results, they should use -from=$end_streamtoken, to=END. - - Events ------ @@ -120,7 +115,7 @@ Stream`_ and |/rooms//messages|_ APIs. For reading events, the intended flow of operation is to call $PREFIX/initialSync, which returns all of the state and the last N events in the -event stream for each room, including `start` and `end` values describing the +event stream for each room, including ``start`` and ``end`` values describing the pagination of each room's event stream. For instance, $PREFIX/initialSync?limit=5 might return the events for a room in the rooms[0].messages.chunk[] array, with tokens describing the start and end of the @@ -135,8 +130,8 @@ You can visualise the range of events being returned as:: start: '1-2-3' end: 'a-b-c' Now, to receive future events in realtime on the eventstream, you simply GET -$PREFIX/events with a `from` parameter of 'a-b-c': in other words passing in the -`end` token returned by initialsync. The request blocks until new events are +$PREFIX/events with a ``from`` parameter of 'a-b-c': in other words passing in the +``end`` token returned by initialsync. The request blocks until new events are available or until your specified timeout elapses, and then returns a new paginatable chunk of events alongside new start and end parameters:: @@ -146,13 +141,13 @@ new paginatable chunk of events alongside new start and end parameters:: | end: 'x-y-z' start: 'a-b-c' -To resume polling the events stream, you pass in the new `end` token as the -`from` parameter of $PREFIX/events and poll again. +To resume polling the events stream, you pass in the new ``end`` token as the +``from`` parameter of $PREFIX/events and poll again. Similarly, to paginate events backwards in order to lazy-load in previous history from the room, you simply GET $PREFIX/rooms//messages -specifying the `from` token to paginate backwards from and a limit of the number -of messages to retrieve. For instance, calling this API with a `from` parameter +specifying the ``from`` token to paginate backwards from and a limit of the number +of messages to retrieve. For instance, calling this API with a ``from`` parameter of '1-2-3' and a limit of 5 would return: [E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]->[E10] @@ -161,7 +156,7 @@ of '1-2-3' and a limit of 5 would return: start: 'u-v-w' end: '1-2-3' To continue paginating backwards, one calls the /messages API again, supplying -the new `start` value as the `from` parameter. +the new ``start`` value as the ``from`` parameter. Receiving live updates on a client @@ -176,8 +171,10 @@ event stream. When the request returns, an ``end`` token is included in the response. This token can be used in the next request to continue where the last request left off. -All events must be deduplicated based on their event ID (TODO: is this actually -a hard requirement in CS v2?) +All events must be deduplicated based on their event ID. + +.. TODO + is deduplication actually a hard requirement in CS v2? .. TODO-spec Do we ever return multiple events in a single request? @@ -364,12 +361,10 @@ There are several APIs provided to ``GET`` events for a room: |/rooms//messages|_ Description: - Get all ``m.room.message`` and ``m.room.member`` events. This API supports + Get all events from the room's timeline. This API supports pagination using ``from`` and ``to`` query parameters, coupled with the ``start`` and ``end`` tokens from an |initialSync|_ API. - XXX: Is this accurate? Doesn't it return all events - not just m.room.message/member? - Response format: ``{ "start": "", "end": "" }`` Example: @@ -399,9 +394,10 @@ is the event that caused it to be redacted, which may include a reason. Redacting an event cannot be undone, allowing server owners to delete the offending content from the databases. -Currently, only room admins can redact events by sending a ``m.room.redaction`` -event, but server admins also need to be able to redact events by a similar -mechanism. +.. TODO + Currently, only room admins can redact events by sending a ``m.room.redaction`` + event, but server admins also need to be able to redact events by a similar + mechanism. Upon receipt of a redaction event, the server should strip off any keys not in the following list: @@ -427,6 +423,9 @@ one of the following event types: and ``redact_level`` - ``m.room.aliases`` allows key ``aliases`` +.. TODO + Need to update m.room.power_levels to reflect new power levels formatting + The redaction event should be added under the key ``redacted_because``. diff --git a/specification/20_events.rst b/specification/20_events.rst index 84a40a11..57b4c925 100644 --- a/specification/20_events.rst +++ b/specification/20_events.rst @@ -448,21 +448,34 @@ outlined below: .. TODO-spec Make the definitions "inherit" from FileInfo where necessary... -Presence Events (v1) -~~~~~~~~~~~~~~~~~~~~ +Presence Events +~~~~~~~~~~~~~~~ ``m.presence`` Summary: Informs you of a user's presence state changes. + Type: Presence event + JSON format:: - { "displayname": "utf-8 string", + + { + "displayname": "utf-8 string", "avatar_url": "url", "presence": "enum [ online|unavailable|offline|free_for_chat|hidden ]", - "last_active_ago": "milliseconds" } - Example: - ``{ "displayname": "Matthew", "avatar_url": "mxc://domain/id", "presence": "online", "last_active_ago": 10000 }`` + "last_active_ago": "milliseconds" + } + + Example:: + + { + "displayname": "Matthew", + "avatar_url": "mxc://domain/id", + "presence": "online", + "last_active_ago": 10000 + } + Description: Each user has the concept of presence information. This encodes the "availability" of that user, suitable for display on other user's clients. @@ -539,8 +552,17 @@ This event is sent by the caller when they wish to establish a call. Optional keys: None. - Example: - ``{ "version" : 0, "call_id": "12345", "offer": { "type" : "offer", "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" } }`` + + Example:: + + { + "version" : 0, + "call_id": "12345", + "offer": { + "type" : "offer", + "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" + } + } ``Offer Object`` Required keys: diff --git a/specification/42_push_overview.rst b/specification/42_push_overview.rst index 913b149f..972a8eea 100644 --- a/specification/42_push_overview.rst +++ b/specification/42_push_overview.rst @@ -1,5 +1,8 @@ -Push Notifications Overview -=========================== +Push Notifications +================== + +Overview +-------- :: diff --git a/specification/43_push_cs_api.rst b/specification/43_push_cs_api.rst index 3f235010..aa09fef8 100644 --- a/specification/43_push_cs_api.rst +++ b/specification/43_push_cs_api.rst @@ -1,8 +1,6 @@ -Push Notifications HTTP API -=========================== +Pushers HTTP API +---------------- -Pushers -------- To receive any notification pokes at all, it is necessary to configure a 'pusher' on the Home Server that you wish to receive notifications from. There is a single API endpoint for this:: @@ -239,8 +237,8 @@ Actions that have no parameters are represented as a string. Otherwise, they are represented as a dictionary with a key equal to their name and other keys as their parameters, eg. { "set_tweak": "sound", "value": "default" } -Push Rule Actions: Tweaks -------------------------- +Push Rules: Actions: Tweaks +--------------------------- The 'set_tweak' key action is used to add an entry to the 'tweaks' dictionary that is sent in the notification poke. The following tweaks are defined: @@ -261,8 +259,8 @@ notification light on a mobile device. If a kind of tweak that a client understands is not specified in an action, the client may choose a sensible behaviour for the tweak. -Push Rules: Conditions: ------------------------ +Push Rules: Conditions +---------------------- Override, Underride and Default rules have a list of 'conditions'. All conditions must hold true for an event in order for a rule to be applied to an event. A rule with no conditions always matches. Matrix specifies the following diff --git a/specification/44_push_push_gw_api.rst b/specification/44_push_push_gw_api.rst index 8890ce5a..b182503b 100644 --- a/specification/44_push_push_gw_api.rst +++ b/specification/44_push_push_gw_api.rst @@ -1,5 +1,6 @@ -Push Notifications: HTTP Notification Protocol -============================================== +HTTP Notification Protocol +-------------------------- + This describes the format used by "http" pushers to send notifications of events.