From 31ae4b38597f57c6026de29a7fd9044d6e632a61 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 8 Oct 2015 13:08:21 +0100 Subject: [PATCH] Swaggerify push notification API Edit units.py to support nested JSON request keys --- api/check_examples.py | 2 +- api/client-server/v1/push_notifier.yaml | 194 ++++++++++++++++++ specification/modules/push.rst | 7 +- .../matrix_templates/templates/http-api.tmpl | 12 +- templating/matrix_templates/units.py | 13 ++ 5 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 api/client-server/v1/push_notifier.yaml diff --git a/api/check_examples.py b/api/check_examples.py index 0622bfeb..ee3c773c 100755 --- a/api/check_examples.py +++ b/api/check_examples.py @@ -51,7 +51,7 @@ def check_parameter(filepath, request, parameter): schema['id'] = fileurl jsonschema.validate(example, schema) except Exception as e: - raise ValueError("Error validating JSON schema for %r %r" % ( + raise ValueError("Error validating JSON schema for %r" % ( request ), e) diff --git a/api/client-server/v1/push_notifier.yaml b/api/client-server/v1/push_notifier.yaml new file mode 100644 index 00000000..54576b6c --- /dev/null +++ b/api/client-server/v1/push_notifier.yaml @@ -0,0 +1,194 @@ +swagger: '2.0' +info: + title: "Matrix Push Notification API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/push/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/notify": + post: + summary: Notify a push gateway about an event. + description: |- + This endpoint is invoked by HTTP pushers to notify a push gateway about + an event. + *NB: Notifications are send to the URL configured when the pusher is + created. This means that the HTTP path may be different depending on the + push gateway.* + parameters: + - in: body + name: notification + description: Information about the push notification. + required: true + schema: + type: object + example: |- + { + "notification": { + "id": "$3957tyerfgewrf384", + "room_id": "!slw48wfj34rtnrf:example.com", + "type": "m.room.message", + "sender": "@exampleuser:matrix.org", + "sender_display_name": "Major Tom", + "room_name": "Mission Control", + "room_alias": "#exampleroom:matrix.org", + "prio": "high", + "content": { + "msgtype": "m.text", + "body": "I'm floating in a most peculiar way." + } + }, + "counts": { + "unread" : 2, + "missed_calls": 1 + }, + "devices": [ + { + "app_id": "org.matrix.matrixConsole.ios", + "pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/", + "pushkey_ts": 12345678, + "data" : {}, + "tweaks": { + "sound": "bing" + } + } + ] + } + required: ["notification", "counts", "devices"] + properties: + notification: + type: object + description: Information about the push notification + required: ["id", "room_id", "type", "sender"] + properties: + id: + type: string + description: |- + An identifier for this notification that may be used to + detect duplicate notification requests. This is not + necessarily the ID of the event that triggered the + notification. + room_id: + type: string + description: The ID of the room in which this event occurred. + type: + type: string + description: The type of the event as in the event's ``type`` field. + sender: + type: string + description: The sender of the event as in the corresponding event field. + sender_display_name: + type: string + description: |- + The current display name of the sender in the room in which + the event occurred. + room_name: + type: string + description: The name of the room in which the event occurred. + room_alias: + type: string + description: An alias to display for the room in which the event occurred. + prio: + type: string + enum: ["high", "low"] + description: |- + The priority of the notification. If omitted, ``high`` is + assumed. This may be used by push gateways to deliver less + time-sensitive notifications in a way that will preserve + battery power on mobile devices. + content: + type: object + title: EventContent + properties: + body: + type: string + description: Message text + description: |- + The ``content`` field from the event, if present. If the + event had no content field, this field is omitted. + counts: + type: object + description: |- + This is a dictionary of the current number of unacknowledged + communications for the recipient user. Counts whose value is + zero are omitted. + properties: + unread: + type: integer + description: |- + The number of unread messages a user has across all of the + rooms they are a member of. + missed_calls: + type: integer + description: |- + The number of unacknowledged missed calls a user has + across all rooms of which they are a member. + devices: + type: array + title: Devices + description: |- + This is an array of devices that the notification should be sent to. + items: + type: object + properties: + app_id: + type: string + description: |- + The app_id given when the pusher was created. + pushkey: + type: string + description: The pushkey given when the pusher was created. + pushkey_ts: + type: integer + description: |- + The unix timestamp (in seconds) when the + pushkey was last updated. + data: + type: object + description: |- + A dictionary of additional pusher-specific data. For + 'http' pushers, this is the data dictionary passed in at + pusher creation minus the ``url`` key. + tweaks: + type: object + description: |- + A dictionary of customisations made to the way this + notification is to be presented. These are added by push rules. + properties: + sound: + type: string + description: |- + Sets the sound file that should be played. + ``default`` means that a default sound should be played. + responses: + 200: + description: A list of rejected push keys. + examples: + application/json: |- + { + "rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ] + } + schema: + type: object # empty json object + properties: + rejected: + type: array + description: |- + A list of all pushkeys given in the notification request that + are not valid. These could have been rejected by an upstream + gateway because they have expired or have never been valid. + Homeservers must cease sending notification requests for these + pushkeys and remove the associated pushers. It may not + necessarily be the notification in the request that failed: + it could be that a previous notification to the same pushkey + failed. + items: + type: string + description: A pushkey + diff --git a/specification/modules/push.rst b/specification/modules/push.rst index ab3f0bf0..bc76f5d6 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -395,12 +395,13 @@ sender and content rules):: Server behaviour ---------------- -HTTP Notification Protocol -~~~~~~~~~~~~~~~~~~~~~~~~~~ - This describes the format used by "HTTP" pushers to send notifications of events. +{{push_notifier_http_api}} + + + Notifications are sent as HTTP POST requests to the URL configured when the pusher is created, but Matrix strongly recommends that the path should be:: diff --git a/templating/matrix_templates/templates/http-api.tmpl b/templating/matrix_templates/templates/http-api.tmpl index 33b2cc98..787f02ca 100644 --- a/templating/matrix_templates/templates/http-api.tmpl +++ b/templating/matrix_templates/templates/http-api.tmpl @@ -13,17 +13,17 @@ Request format: -====================== ================= =========================================== - Parameter Value Description -====================== ================= =========================================== +=================================== ================= =========================================== + Parameter Value Description +=================================== ================= =========================================== {% for loc in endpoint.req_param_by_loc -%} *{{loc}} parameters* ------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------- {% for param in endpoint.req_param_by_loc[loc] -%} -{{param.key}}{{param.type|indent(23-param.key|length)}}{{param.desc|indent(18-param.type|length)|wrap(43)|indent_block(41)}} +{{param.key}}{{param.type|indent(36-param.key|length)}}{{param.desc|indent(18-param.type|length)|wrap(43)|indent_block(54)}} {% endfor -%} {% endfor -%} -====================== ================= =========================================== +=================================== ================= =========================================== {% if endpoint.res_tables|length > 0 -%} Response format: diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index c3be2b60..558461b9 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -228,6 +228,19 @@ class MatrixUnits(Units): "type": json_body[key]["type"], "desc": pdesc }) + if json_body[key]["type"] in ["object"]: + req_tables = get_json_schema_object_fields( + json_body[key] + ) + for table in req_tables: + for row in table["rows"]: + endpoint["req_params"].append({ + "key": key + "." + row["key"], + "loc": "JSON body", + "type": row["type"], + "desc": row["req_str"] + row["desc"] + }) + # endfor[param] for row in endpoint["req_params"]: self.log("Request parameter: %s" % row)