CLOUDMORROW

Resources / User handbook

Push notifications

What reaches your phone, and when.

Push notifications

A web app on an iOS home screen is not a process most of the time — it is an icon and a screenshot. Nothing it could poll would keep the count on that icon right, so the count on the icon needs a real push: the browser vendor's service wakes a service worker, and the worker shows the banner and sets the badge. That is what server/webpush.py is.

Three specifications, implemented rather than installed, because the server's dependencies already cover them (pyjwt, cryptography, and the standard library):

  • RFC 8030 — a POST to the endpoint the browser gave us.
  • RFC 8292 (VAPID) — an ES256 JWT saying which push service the message is for and when it expires, signed with a P-256 key in <data_dir>/vapid.key, generated on first use at mode 600. The public half is what the browser subscribes with, which is what ties the two together. Lose the file and no data goes with it, but every device has to be asked again — so back it up with the database.
  • RFC 8291 / 8188 (aes128gcm) — the body, encrypted to the subscription's own key, so the push service carries something it cannot read.

The number on the icon is everything waiting: everything unread in the spaces you are in — a channel's messages, or whatever another Quill declares unread — plus unread notifications. It is worked out in one place (/api/push/badge) so the page, the service worker and the push payload cannot disagree about it. Each push carries the recipient's own badge, which is why a message to four people is four requests rather than one.

On iOS none of this exists until the app is on the home screen — in a Safari tab there is no service worker to push and setAppBadge does nothing. So Me says which of those situations you are in rather than offering a button that cannot work: add it to the Home Screen, open it from there, and Turn on appears. Only on iOS: a computer's browser, and Android's, push to a plain tab, so there Turn on is there at once and asks the browser for permission the way any site does. A tab gets the banner while the browser is running; the count on the icon is the installed app's. Once it is on, Send a test pushes you, because everything between the server and the banner fails silently and otherwise the only test is asking somebody to message you. Everything behind the bell is pushed too, not only messages, and the bell's list offers Turn on as well until it is on.

Set push_subject in the server config to the mailto: or https: URL a push service should complain to. Left empty it is derived from public_url, which is the truest answer the server has on its own.

Signing out does not unsubscribe the device: signing out of the phone app and back in is routine, and asking iOS for permission again each time is the quickest way to have it refused for good.

From docs/MANUAL.md in the Cloudmorrow repository. Something wrong? A pull request there fixes it here.