Skip to content

Instantly share code, notes, and snippets.

@indigane
Last active December 8, 2023 19:45
Show Gist options
  • Save indigane/70ed13d5287c2d18b3e8e5d4f0c6d119 to your computer and use it in GitHub Desktop.
Save indigane/70ed13d5287c2d18b3e8e5d4f0c6d119 to your computer and use it in GitHub Desktop.

Push API specification for self-hosting already exists but we're not using it

Date: 2023-12-07

To keep this as short as possible and to get to the point, I'll skip the "why" and let's just say you have an inexplicable urge to self-host push notifications.

I use the term "self-host" here only because it is an easy shorthand. To be honest, I don't want to self-host anything if I can avoid it. But when it becomes technically possible to self-host something, then I can pay someone I (relatively) trust to do it. Think providers like Mullvad, Proton or Tuta. That's the end goal, not self-hosting per se.

I'll also be using the terminology from the diagram below this text. The terminology around push technologies varies a lot.

Back to the urge. When my brain goes idle, it tries to solve things that have frustrated me recently. Self-hosted push notifications is one of those things on a long list of others. The solution it used to come up with was imagining an alternate universe, where we had somehow convinced everyone to agree on a Push API specification, in which the user can set a custom push server URL. Then my conscious mind pushed that thought away, because "that would never work for a multitude of reasons", which I'm sure some of you agree with.

I then felt really dumb when I eventually did a deep dive into the Web Push API, and realized that we already have exactly that, and its been in production use for a relatively long time.

And on top of that, since no one can trust anyone on the web, it is also end-to-end encrypted.

Don't be fooled by the name. While it's called Web Push API, the specification does not care whether your device is a browser environment or an Android phone and neither does the application server.

Here's a quick primer into how it works, simplifying a bit for brevity.

The browser exposes a JavaScript API, with a method getSubscription() that returns JSON as below, which is then sent to and stored by the application server.

{
  "endpoint": "https://push-server.browser-vendor.test/subscription/id/...",
  "expirationTime": null,
  "keys": {
    "p256dh": "...",
    "auth": "..."
  }
}

The "endpoint" property is both the push API endpoint and the subscription ID.

If you ignore the encryption, which is what the "keys" property is for, it is astonishingly simple.

To send a push message, the application server sends a POST request to the "endpoint" URL. The push message content is the POST body.

And there it is! Every browser vendor has their own push server, but nothing in the specification prevents you from hosting your own and replacing the "endpoint".

Go ahead and try it out. You can use the browser debugger to change the "endpoint" before it is sent to the application server. For the sake of testing, you can use ntfy.sh as the push server. Just replace the "endpoint" with "https://ntfy.sh/arbitrary-string-here" and use any of the ntfy clients to listen for messages sent to that endpoint. As of writing, ntfy doesn't support the encryption part yet, so you'll receive binary blobs.

If you do try it out though you'll soon enough realize, as I did, that the biggest obstacle is that no one uses Web Push, except for the spam industry.

Even if a web app you use supports desktop notifications, it is most likely only using the Notification API, not the Push API.

While that's not the only obstacle it is the biggest one.

This gets us back to the title. You might be wondering what I mean by "we".

I wish I could say that I mean anyone who wants to self-host or use self-hosted push notifications.

But since the biggest obstacle is applications, "we" also includes application developers, who have other priorities than catering to niches like this, even if they're developing a privacy focused app (looking at you Signal).

When I came out of the Web Push API deep dive, I had hoped that the obstacles were limited to having

  • a push client
  • a push server
  • communication between the push client and the application client

The first two of which can almost already be solved by things like UnifiedPush and ntfy.sh or Mozilla's autopush-rs.

UnifiedPush offers a solution for the communication part as well but it would, again, require cooperation from application developers. This isn't a must-have for the MVP though, as you could still receive the notifications, and maybe eventually get enough critical mass for application developers to care.

But since the gate-keeper here is applications not using Web Push at all, it's a lot more hopeless.

On the bright side, I think that an even bigger obstacle has already been overcome. That is the Push API specification I used to daydream about. With it, I feel like we are on the verge of this being possible.

So I am writing this in the hope that we, as in anyone part of the diagram, some day decide to use the Push API.

Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment