14
Let's describe the push system by way of an example.
16
Alice has written a chat application called Chatter. Using it, Bob can send messages to Carol and viceversa. Alice has a
17
web application for it, so the way it works now is that Bob connects to the service, posts a message, and when Carol
18
connects, she gets it. If Carol leaves the browser window open, it beeps when messages arrive.
20
Now Alice wants to create an Ubuntu Touch app for Chatter, so she implements the same architecture using a client that
21
does the same thing as the web browser. Sadly, since applications on Ubuntu Touch don't run continuously, messages are
22
only delivered when Carol opens the app, and the user experience suffers.
24
Using the Ubuntu Push Server, this problem is alleviated: the Chatter server will deliver the messages to the Ubuntu
25
Push Server, which in turn will send it in an efficient manner to the Ubuntu Push Client running in Bob and Carol's
26
devices. The user sees a notification (all without starting the app) and then can launch it if he's interested in
27
reading messages at that point.
29
Since the app is not started and messages are delivered oportunistically, this is both battery and bandwidth-efficient.
33
The Ubuntu Push system provides:
35
* A push server which receives **push messages** from the app servers, queues them and delivers them efficiently
37
* A push client which receives those messages, queues messages to the app and displays notifications to the user
39
The full lifecycle of a push message is:
41
* Created in a application-specific server
42
* Sent to the Ubuntu Push server, targeted at a user or user+device pair
43
* Delivered to one or more Ubuntu devices
44
* Passed through the application helper for processing
45
* Notification displayed to the user (via different mechanisms)
46
* Application Message queued for the app's use
48
If the user interacts with the notification, the application is launched and should check its queue for messages
51
For the app developer, there are several components needed:
53
* A server that sends the **push messages** to the Ubuntu Push server
54
* Support in the client app for registering with the Ubuntu Push client
55
* Support in the client app to react to **notifications** displayed to the user and process **application messages**
56
* A helper program with application-specific knowledge that transforms **push messages** as needed.
58
In the following sections, we'll see how to implement all the client side parts. For the application server, see the
59
`Ubuntu Push Server API section <#ubuntu-push-server-api>`__
16
.. include:: _description.txt
61
18
The PushClient Component
62
19
------------------------
126
83
The ``count`` property sets the counter in the application's icon to the given value.
132
The payload delivered to push-client will be passed onto a helper program that can modify it as needed before passing it onto
133
the postal service (see `Helper Output Format <#helper-output-format>`__).
135
The helper receives two arguments ``infile`` and ``outfile``. The message is delivered via ``infile`` and the transformed
136
version is placed in ``outfile``.
138
This is the simplest possible useful helper, which simply passes the message through unchanged::
143
f1, f2 = sys.argv[1:3]
144
open(f2, "w").write(open(f1).read())
146
Helpers need to be added to the click package manifest::
149
"name": "com.ubuntu.developer.ralsina.hello",
150
"description": "description of hello",
151
"framework": "ubuntu-sdk-14.10-qml-dev2",
152
"architecture": "all",
156
"apparmor": "hello.json",
157
"desktop": "hello.desktop"
160
"apparmor": "helloHelper-apparmor.json",
161
"push-helper": "helloHelper.json"
165
"maintainer": "Roberto Alsina <roberto.alsina@canonical.com>"
168
Here, we created a helloHelper entry in hooks that has an apparmor profile and an additional JSON file for the push-helper hook.
170
helloHelper-apparmor.json must contain **only** the push-notification-client policy group::
174
"push-notification-client"
176
"policy_version": 1.2
179
And helloHelper.json must have at least a exec key with the path to the helper executable relative to the json, and optionally
180
an app_id key containing the short id of one of the apps in the package (in the format packagename_appname without a version).
181
If the app_id is not specified, the helper will be used for all apps in the package::
184
"exec": "helloHelper",
185
"app_id": "com.ubuntu.developer.ralsina.hello_hello"
188
.. note:: For deb packages, helpers should be installed into /usr/lib/ubuntu-push-client/legacy-helpers/ as part of the package.
193
Helpers output has two parts, the postal message (in the "message" key) and a notification to be presented to the user (in the "notification" key).
195
Here's a simple example::
206
"timestamp": 1407160197
210
"pattern": [200, 100],
220
The notification can contain a **tag** field, which can later be used by the `persistent notification management API. <#persistent-notification-management>`__
222
:message: (optional) A JSON object that is passed as-is to the application via PopAll.
223
:notification: (optional) Describes the user-facing notifications triggered by this push message.
225
The notification can contain a **card**. A card describes a specific notification to be given to the user,
226
and has the following fields:
228
:summary: (required) a title. The card will not be presented if this is missing.
229
:body: longer text, defaults to empty.
230
:actions: If empty (the default), a bubble notification is non-clickable.
231
If you add a URL, then bubble notifications are clickable and launch that URL. One use for this is using a URL like
232
``appid://com.ubuntu.developer.ralsina.hello/hello/current-user-version`` which will switch to the app or launch
233
it if it's not running. See `URLDispatcher <https://wiki.ubuntu.com/URLDispatcher>`__ for more information.
235
:icon: An icon relating to the event being notified. Defaults to empty (no icon);
236
a secondary icon relating to the application will be shown as well, regardless of this field.
237
:timestamp: Seconds since the unix epoch, only used for persist (for now). If zero or unset, defaults to current timestamp.
238
:persist: Whether to show in notification centre; defaults to false
239
:popup: Whether to show in a bubble. Users can disable this, and can easily miss them, so don't rely on it exclusively. Defaults to false.
241
.. note:: Keep in mind that the precise way in which each field is presented to the user depends on factors such as
242
whether it's shown as a bubble or in the notification centre, or even the version of Ubuntu Touch the user
245
The notification can contain a **sound** field. This is either a boolean (play a predetermined sound) or the path to a sound file. The user can disable it, so don't rely on it exclusively.
246
Defaults to empty (no sound). The path is relative, and will be looked up in (a) the application's .local/share/<pkgname>, and (b)
249
The notification can contain a **vibrate** field, causing haptic feedback, which can be either a boolean (if true, vibrate a predetermined way) or an object that has the following content:
251
:pattern: a list of integers describing a vibration pattern (duration of alternating vibration/no vibration times, in milliseconds).
252
:repeat: number of times the pattern has to be repeated (defaults to 1, 0 is the same as 1).
254
The notification can contain a **emblem-counter** field, with the following content:
256
:count: a number to be displayed over the application's icon in the launcher.
257
:visible: set to true to show the counter, or false to hide it.
259
.. note:: Unlike other notifications, emblem-counter needs to be cleaned by the app itself.
260
Please see `the persistent notification management section. <#persistent-notification-management>`__
262
.. FIXME crosslink to hello example app on each method
267
To use the push API, applications need to request permission in their security profile, using something like this::
272
"push-notification-client"
274
"policy_version": 1.2
278
Ubuntu Push Server API
279
----------------------
281
The Ubuntu Push server is located at https://push.ubuntu.com and has a single endpoint: ``/notify``.
282
To notify a user, your application has to do a POST with ``Content-type: application/json``.
284
Here is an example of the POST body using all the fields::
287
"appid": "com.ubuntu.music_music",
288
"expire_on": "2014-10-08T14:48:00.000Z",
289
"token": "LeA4tRQG9hhEkuhngdouoA==",
290
"clear_pending": true,
291
"replace_tag": "tagname",
300
"timestamp": 1407160197
305
"pattern": [200, 100],
317
:appid: ID of the application that will receive the notification, as described in the client side documentation.
318
:expire_on: Expiration date/time for this message, in `ISO8601 Extendend format <http://en.wikipedia.org/wiki/ISO_8601>`__
319
:token: The token identifying the user+device to which the message is directed, as described in the client side documentation.
320
:clear_pending: Discards all previous pending notifications. Usually in response to getting a "too-many-pending" error.
321
:replace_tag: If there's a pending notification with the same tag, delete it before queuing this new one.
322
:data: A JSON object.
324
In this example, data is `what a helper would output <#helper-output-format>`__ but that's not necessarily the case.
325
The content of the data field will be passed to the helper application which **has** to produce output in that format.
85
.. include:: _common.txt
b'\\ No newline at end of file'