diff --git a/event-schemas/examples/v1/m.receipt b/event-schemas/examples/v1/m.receipt new file mode 100644 index 00000000..83515317 --- /dev/null +++ b/event-schemas/examples/v1/m.receipt @@ -0,0 +1,13 @@ +{ + "type": "m.receipt", + "room_id": "!KpjVgQyZpzBwvMBsnT:matrix.org", + "content": { + "$1435641916114394fHBLK:matrix.org": { + "read": { + "@rikj:jki.re": { + "ts": 1436451550453 + } + } + } + } +} diff --git a/event-schemas/schema/v1/m.receipt b/event-schemas/schema/v1/m.receipt new file mode 100644 index 00000000..4bd9f17b --- /dev/null +++ b/event-schemas/schema/v1/m.receipt @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "Receipt Event", + "description": "Informs the client of new receipts.", + "properties": { + "content": { + "type": "object", + "description": "The event ids which the receipts relate to.", + "patternProperties": { + "^\\$": { + "type": "object", + "description": "The types of the receipts.", + "additionalProperties": { + "type": "object", + "description": "User ids of the receipts", + "patternProperties": { + "^@": { + "type": "object", + "properties": { + "ts": { + "type": "number", + "description": "The timestamp the receipt was sent at" + } + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + "type": { + "type": "string", + "enum": ["m.receipt"] + }, + "room_id": { + "type": "string" + } + }, + "required": ["room_id", "type", "content"] +} diff --git a/scripts/continuserv/README b/scripts/continuserv/README new file mode 100644 index 00000000..8ce37850 --- /dev/null +++ b/scripts/continuserv/README @@ -0,0 +1,6 @@ +continuserv proactively re-generates the spec on filesystem changes, and serves it over HTTP. + +To run it, you must install the `go` tool. You will also need to install fsnotify by running: + `go get gopkg.in/fsnotify.v1` +You can then run continuserv by running: + `go run main.go` diff --git a/scripts/continuserv/main.go b/scripts/continuserv/main.go index c5d623a4..e7757c06 100644 --- a/scripts/continuserv/main.go +++ b/scripts/continuserv/main.go @@ -68,6 +68,7 @@ func watchFS(ch chan struct{}, w *fsnotify.Watcher) { case e := <-w.Events: if filter(e) { wg.Add(1) + fmt.Printf("Noticed change to %s, re-generating spec\n", e.Name) ch <- struct{}{} } } @@ -79,7 +80,9 @@ func makeWalker(w *fsnotify.Watcher) filepath.WalkFunc { if err != nil { log.Fatalf("Error walking: %v", err) } - w.Add(path) + if err := w.Add(path); err != nil { + log.Fatalf("Failed to add watch: %v", err) + } return nil } } diff --git a/specification/46_receipts.rst b/specification/46_receipts.rst new file mode 100644 index 00000000..6428d6b5 --- /dev/null +++ b/specification/46_receipts.rst @@ -0,0 +1,81 @@ +Receipts +======== + +Receipts are used to publish which events in a room the user or their devices +have interacted with. For example, which events the user has read. + +For efficiency this is done as "up to" markers, i.e. marking a particular event +as, say, ``read`` indicates the user has read all events *up to* that event. + +Client-Server API +----------------- + +Clients will receive receipts in the following format:: + + { + "type": "m.receipt", + "room_id": , + "content": { + : { + : { + : { "ts": , ... }, + ... + } + }, + ... + } + } + +For example:: + + { + "type": "m.receipt", + "room_id": "!KpjVgQyZpzBwvMBsnT:matrix.org", + "content": { + "$1435641916114394fHBLK:matrix.org": { + "read": { + "@erikj:jki.re": { "ts": 1436451550453 }, + ... + } + }, + ... + } + } + +For efficiency, receipts are batched into one event per room. In the initialSync +and v2 sync APIs the receipts are listed in a seperate top level ``receipts`` +key. + +Each ``user_id``, ``receipt_type`` pair must be associated with only a single +``event_id``. + +New receipts that come down the event streams are deltas. Deltas update +existing mappings, clobbering based on ``user_id``, ``receipt_type`` pairs. + + +A client can update the markers for its user by issuing a request:: + + POST /_matrix/client/v2_alpha/rooms//receipt/read/ + +Where the contents of the ``POST`` will be included in the content sent to +other users. The server will automatically set the ``ts`` field. + + +Server-Server API +----------------- + +Receipts are sent across federation as EDUs with type ``m.receipt``. The +format of the EDUs are:: + + { + : { + : { + : { } + }, + ... + }, + ... + } + +These are always sent as deltas to previously sent reciepts. + diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index 150b0942..ca870571 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -30,7 +30,7 @@ def get_json_schema_object_fields(obj, enforce_title=False): } tables = [fields] - props = obj.get("properties") + props = obj.get("properties", obj.get("patternProperties")) parents = obj.get("allOf") if not props and not parents: raise Exception(