lots of fixes based on kegan's review of https://github.com/matrix-org/matrix-doc/pull/13

This commit is contained in:
Matthew Hodgson 2015-03-19 14:21:08 +01:00
parent d40f6c1d7c
commit 58c28598af
8 changed files with 112 additions and 85 deletions

View file

@ -5,7 +5,7 @@ Definitions
# *Event* -- A JSON object that represents a piece of information to be # *Event* -- A JSON object that represents a piece of information to be
distributed to the the room. The object includes a payload and metadata, 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. them. It also includes one or more references to previous events.
# *Event graph* -- Events and their references to previous events form a # *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. room, except for a few special circumstances.
# *State event* -- A state event is an event that has a non-null string valued # *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. 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 # *State tree* -- A state tree is a tree formed by a collection of state events

View file

@ -811,8 +811,9 @@ Notes:
Presence API ``[Draft]`` Presence API ``[Draft]``
------------------------ ------------------------
FIXME: this seems to be ignoring activity timers entirely, which were present on .. FIXME
the planning etherpad and are present in the actual HTTP API. Needs attention. 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: The goals of presence are to:

View file

@ -13,11 +13,11 @@ Table of Contents
Introduction Introduction
============ ============
Matrix is a set of open APIs for open-federated Instant Messaging, VoIP and Matrix is a set of open APIs for open-federated Instant Messaging (IM), Voice
Internet of Things communication, designed to create and support a new global over IP (VoIP) and Internet of Things (IoT) communication, designed to create
real-time communication ecosystem. The intention is to provide an open and support a new global real-time communication ecosystem. The intention is to
decentralised pubsub fabric for the internet for securely persisting and provide an open decentralised pubsub layer for the internet for securely
publishing/subscribing JSON objects. persisting and publishing/subscribing JSON objects.
This specification is the ongoing result of standardising the APIs used by the This specification is the ongoing result of standardising the APIs used by the
various components of the Matrix ecosystem to communicate with one another. 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 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 typically messaging/VoIP applications or IoT devices/hubs and communicate by
synchronising communication history with their `homeserver` using the synchronising communication history with their ``homeserver`` using the
`Client-Server API`. Each homeserver stores the communication history and ``Client-Server API``. Each homeserver stores the communication history and
account information for all of its clients, and shares data with the wider account information for all of its clients, and shares data with the wider
Matrix ecosystem by synchronising communication history with other homeservers Matrix ecosystem by synchronising communication history with other homeservers
and their clients. and their clients.
Clients typically communicate with each other by emitting events in the 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 homeservers* whose users are participating in a given room. As such, *no
single homeserver has control or ownership over a given room*. Homeservers single homeserver has control or ownership over a given room*. Homeservers
model communication history as a partially ordered graph of events known as model communication history as a partially ordered graph of events known as
the room's `event graph`, which is synchronised with eventual consistency the room's ``event graph``, which is synchronised with eventual consistency
between the participating servers using the Server-Server API. Matrix optimises between the participating servers using the ``Server-Server API``. This process
for the the Availability and Partitioned properties of CAP theorem at the of synchronising shared conversation history between homeservers run by
expense of Consistency. 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 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 HTTP PUT of the required JSON event on its homeserver (HS) using the
@ -144,6 +146,7 @@ a long-lived GET request.
| |<--------( HTTPS )----------| | | |<--------( HTTPS )----------| |
+------------------+ Server-Server API +------------------+ +------------------+ Server-Server API +------------------+
History Synchronisation History Synchronisation
(Federation)
Users Users
@ -179,11 +182,11 @@ Event Graphs
~~~~~~~~~~~~ ~~~~~~~~~~~~
Events exchanged in the context of a room are stored in a directed acyclic graph 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 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 list of zero or more ``parent`` events, which refer to any preceeding events
have no chronological successor from the perspective of the homeserver which which have no chronological successor from the perspective of the homeserver
created the event. which created the event.
Typically an event has a single parent: the most recent message in the room at 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 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. Every event graph has a single root event with no parent.
To order and ease chronological comparison between the events within the graph, 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` homeservers maintain a ``depth`` metadata field on each event. An event's
is a positive integer that is strictly greater than the depths of any of its ``depth`` is a positive integer that is strictly greater than the depths of any
parents. The root event should have a depth of 1. Thus if one event is before of its parents. The root event should have a depth of 1. Thus if one event is
another, then it must have a strictly smaller depth. before another, then it must have a strictly smaller depth.
Room structure Room structure
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -229,7 +232,7 @@ the room ``!qporfwt:matrix.org``::
| matrix.org | | domain.com | | matrix.org | | domain.com |
+------------------+ +------------------+ +------------------+ +------------------+
| ^ | ^
| [HTTP POST] | | [HTTP PUT] |
| Room ID: !qporfwt:matrix.org | | Room ID: !qporfwt:matrix.org |
| Event type: m.room.message | | Event type: m.room.message |
| Content: { JSON object } | | 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 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 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, it saw a pro-active event from the user. Any event which could be triggered by a
coming online or back from idle, etc. This timestamp is presented via a key human using the application is considered pro-active (e.g. sending an event to a
called ``last_active_ago``, which gives the relative number of milliseconds 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. 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. 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 as a human readable ``display name``, a profile photo URL, contact information
(email address, phone nubers, website URLs etc). (email address, phone nubers, website URLs etc).
Profile data is typed using namespaced keys for interoperability, much like In Client-Server API v2, profile data is typed using namespaced keys for
events - e.g. ``m.profile.display_name``. 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 Actually specify the different types of data - e.g. what format are display
names allowed to be? 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 client preferences, or server configuration settings which lack any other
dedicated API. The API is symmetrical to managing Profile data. 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 & Would it really be overengineered to use the same API for both profile &
private user data, but with different ACLs? 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 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 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 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 _. codes should have their namespace first in ALL CAPS, followed by a single _ to
For example, if there was a custom namespace ``com.mydomain.here``, and a 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 ``FORBIDDEN`` code, the error code should look like
``COM.MYDOMAIN.HERE_FORBIDDEN``. There may be additional keys depending on the ``COM.MYDOMAIN.HERE_FORBIDDEN``. There may be additional keys depending on the
error, but the keys ``error`` and ``errcode`` MUST always be present. 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: Some standard error codes are below:
:``M_FORBIDDEN``: :``M_FORBIDDEN``:

View file

@ -20,10 +20,10 @@ Pagination
Querying large datasets in Matrix always uses the same pagination API pattern to 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 to give clients a consistent way of selecting subsets of a potentially changing
dataset. Requests pass in `from`, `to` and `limit` parameters which describe dataset. Requests pass in ``from``, ``to`` and ``limit`` parameters which describe
where to read from the stream. `from` and `to` are opaque textual 'stream where to read from the stream. ``from`` and ``to`` are opaque textual 'stream
tokens' which describe positions in the dataset. The response returns new 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. requests to continue pagination.
Pagination Request Query Parameters Pagination Request Query Parameters
@ -35,13 +35,13 @@ Query parameters:
to: to:
$streamtoken - The opaque token to end streaming at. Typically, $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 clients will not know the item of data to end at, so this will usually be
START or END. omitted.
limit: limit:
integer - An integer representing the maximum number of items to integer - An integer representing the maximum number of items to
return. return.
'START' and 'END' are magic token values which specify the start and end of the 'START' and 'END' are placeholder values used in these examples to describe the
dataset respectively. start and end of the dataset respectively.
Unless specified, the default pagination parameters are from=START, to=END, Unless specified, the default pagination parameters are from=START, to=END,
without a limit set. This allows you to hit an API like 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 get the next set of results. The "start" and "end" keys can only be omitted if
the complete dataset is provided in "chunk". 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 Events
------ ------
@ -120,7 +115,7 @@ Stream`_ and |/rooms/<room_id>/messages|_ APIs.
For reading events, the intended flow of operation is to call 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 $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, pagination of each room's event stream. For instance,
$PREFIX/initialSync?limit=5 might return the events for a room in the $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 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' start: '1-2-3' end: 'a-b-c'
Now, to receive future events in realtime on the eventstream, you simply GET 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 $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 ``end`` token returned by initialsync. The request blocks until new events are
available or until your specified timeout elapses, and then returns a available or until your specified timeout elapses, and then returns a
new paginatable chunk of events alongside new start and end parameters:: 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' | end: 'x-y-z'
start: 'a-b-c' start: 'a-b-c'
To resume polling the events stream, you pass in the new `end` token as the To resume polling the events stream, you pass in the new ``end`` token as the
`from` parameter of $PREFIX/events and poll again. ``from`` parameter of $PREFIX/events and poll again.
Similarly, to paginate events backwards in order to lazy-load in previous Similarly, to paginate events backwards in order to lazy-load in previous
history from the room, you simply GET $PREFIX/rooms/<room_id>/messages history from the room, you simply GET $PREFIX/rooms/<room_id>/messages
specifying the `from` token to paginate backwards from and a limit of the number 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 messages to retrieve. For instance, calling this API with a ``from`` parameter
of '1-2-3' and a limit of 5 would return: of '1-2-3' and a limit of 5 would return:
[E0]->[E1]->[E2]->[E3]->[E4]->[E5]->[E6]->[E7]->[E8]->[E9]->[E10] [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' start: 'u-v-w' end: '1-2-3'
To continue paginating backwards, one calls the /messages API again, supplying 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 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 response. This token can be used in the next request to continue where the
last request left off. last request left off.
All events must be deduplicated based on their event ID (TODO: is this actually All events must be deduplicated based on their event ID.
a hard requirement in CS v2?)
.. TODO
is deduplication actually a hard requirement in CS v2?
.. TODO-spec .. TODO-spec
Do we ever return multiple events in a single request? 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/<room_id>/messages|_ |/rooms/<room_id>/messages|_
Description: 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 pagination using ``from`` and ``to`` query parameters, coupled with the
``start`` and ``end`` tokens from an |initialSync|_ API. ``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: Response format:
``{ "start": "<token>", "end": "<token>" }`` ``{ "start": "<token>", "end": "<token>" }``
Example: 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 Redacting an event cannot be undone, allowing server owners to delete the
offending content from the databases. offending content from the databases.
Currently, only room admins can redact events by sending a ``m.room.redaction`` .. TODO
event, but server admins also need to be able to redact events by a similar Currently, only room admins can redact events by sending a ``m.room.redaction``
mechanism. 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 Upon receipt of a redaction event, the server should strip off any keys not in
the following list: the following list:
@ -427,6 +423,9 @@ one of the following event types:
and ``redact_level`` and ``redact_level``
- ``m.room.aliases`` allows key ``aliases`` - ``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``. The redaction event should be added under the key ``redacted_because``.

View file

@ -448,21 +448,34 @@ outlined below:
.. TODO-spec .. TODO-spec
Make the definitions "inherit" from FileInfo where necessary... Make the definitions "inherit" from FileInfo where necessary...
Presence Events (v1) Presence Events
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
``m.presence`` ``m.presence``
Summary: Summary:
Informs you of a user's presence state changes. Informs you of a user's presence state changes.
Type: Type:
Presence event Presence event
JSON format:: JSON format::
{ "displayname": "utf-8 string",
{
"displayname": "utf-8 string",
"avatar_url": "url", "avatar_url": "url",
"presence": "enum [ online|unavailable|offline|free_for_chat|hidden ]", "presence": "enum [ online|unavailable|offline|free_for_chat|hidden ]",
"last_active_ago": "milliseconds" } "last_active_ago": "milliseconds"
Example: }
``{ "displayname": "Matthew", "avatar_url": "mxc://domain/id", "presence": "online", "last_active_ago": 10000 }``
Example::
{
"displayname": "Matthew",
"avatar_url": "mxc://domain/id",
"presence": "online",
"last_active_ago": 10000
}
Description: Description:
Each user has the concept of presence information. This encodes the Each user has the concept of presence information. This encodes the
"availability" of that user, suitable for display on other user's clients. "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: Optional keys:
None. 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`` ``Offer Object``
Required keys: Required keys:

View file

@ -1,5 +1,8 @@
Push Notifications Overview Push Notifications
=========================== ==================
Overview
--------
:: ::

View file

@ -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 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 'pusher' on the Home Server that you wish to receive notifications from. There
is a single API endpoint for this:: 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 represented as a dictionary with a key equal to their name and other keys as
their parameters, eg. { "set_tweak": "sound", "value": "default" } 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 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: 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 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. 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 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 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 event. A rule with no conditions always matches. Matrix specifies the following

View file

@ -1,5 +1,6 @@
Push Notifications: HTTP Notification Protocol HTTP Notification Protocol
============================================== --------------------------
This describes the format used by "http" pushers to send notifications of This describes the format used by "http" pushers to send notifications of
events. events.