From 8a4273489d945f21d7e0ca6aac952460c7d4c391 Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 9 Nov 2023 07:45:35 +0000 Subject: [PATCH] linux push notifs: document Matrix and Prosody integration --- .../index.md | 97 ++++++++++++++++++- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/content/blog/DRAFT-2023-11-06-mobile-linux-push-notifications/index.md b/content/blog/DRAFT-2023-11-06-mobile-linux-push-notifications/index.md index a160e9c..d9d2e14 100644 --- a/content/blog/DRAFT-2023-11-06-mobile-linux-push-notifications/index.md +++ b/content/blog/DRAFT-2023-11-06-mobile-linux-push-notifications/index.md @@ -118,7 +118,7 @@ however, running it this way allows anyone to use your server. the easy way to o ```nix services.ntfy-sh.enable = true; -services.nginx.virtualHosts."MY.HOST" = { +services.nginx.virtualHosts."MY.NTFY.HOST" = { forceSSL = true; listen = [ { addr = "0.0.0.0"; port = 2587; ssl = true; } @@ -136,7 +136,7 @@ services.nginx.virtualHosts."MY.HOST" = { }; services.ntfy-sh.settings = { - base-url = "https://MY.HOST"; + base-url = "https://MY.NTFY.HOST"; behind-proxy = true; auth-default-access = "deny-all"; }; @@ -149,8 +149,99 @@ systemd.services.ntfy-sh.preStart = '' deploy that and subscribe to the https url this time. note the port change to 2587: you still want a unique port against which you can write a wowlan rule, and it's easier to put nginx on a new port than ntfy's default 2586. -if you're thorough, you might notice some spurious wakeups with this setup. ntfy sends keep-alive packets every 45 seconds, but that's no good for us! best is to disable those keep-alives, and only put the phone to sleep for shortish durations (e.g. 10 minutes): i'll revisit the nuances around this near the end. +if you're thorough, you might notice some spurious wakeups with this setup. ntfy sends keep-alive packets every 45 seconds, but that's no good for us! best is to disable those keep-alives, and only put the phone to sleep for shortish durations (e.g. 10 minutes): i'll revisit the nuances around this near the end of this article. ```nix services.ntfy-sh.settings.keepalive-interval = "30m"; ``` + + +### Synapse (Matrix) ntfy integration + +the Synapse Matrix server exposes an API for controlling its push behavior [here](https://spec.matrix.org/unstable/push-gateway-api/). +some of the larger clients, like Fluffychat, can be seen to host their own push gateways, which they point Synapse to via this API. +presumably one could configure these clients to request a different push gateway (i.e. ntfy.sh, or your own instance from just above), +either in the UI or with an edit to their source code. but if you have CLI admin access to Synapse, it's easier to do this generically from the CLI. + +first, grab an auth token for your Matrix account. it looks like `6cC_a03Ty3sTfqvo3FS_x8vEjdvNsxyL5W4mm73` and can be found in Element's "Help & About" settings page. + +then, with this token, open a CLI to wherever you host your synapse server and issue this command to see where it's currently sending notifications (if anywhere): +```sh +$ curl --header "Authorization: Bearer ACCESS_TOKEN" \ + localhost:8008/_matrix/client/v3/pushers \ + | jq . +{ + "pushers": [ + { + "app_display_name": "Element (iOS)", + "app_id": "im.vector.app.ios.prod", + "data": { + "url": "https://matrix.org/_matrix/push/v1/notify", + "format": "event_id_only", + "default_payload": { + "aps": { + "mutable-content": 1, + "alert": { + "loc-key": "Notification", + "loc-args": [] + } + } + } + }, + "device_display_name": "iPhone", + "kind": "http", + "lang": "en-US", + "profile_tag": "1Akvq5DDr159ANj9", + "pushkey": "Bap1n7kqGzF9TuPkiDNDy9wW+cuvfDnxy7Cab7AMsIX=" + } + ] +} +``` + +now, add a new pusher for your ntfy service. this won't replace the existing settings, instead it'll cause push notifications to be sent to two locations simultaneously: + +```sh +$ curl --header "Authorization: Bearer ACCESS_TOKEN" \ + --data '{ \ + "app_display_name": "ntfy-adapter", \ + "app_id": "ntfy.uninsane.org", \ + "data": { \ + "url": "https://MY.NTFY.HOST/_matrix/push/v1/notify", \ + "format": "event_id_only" \ + }, \ + "device_display_name": "ntfy-adapter", \ + "kind": "http", \ + "lang": "en-US", \ + "profile_tag": "", \ + "pushkey": "TEST_WOWLAN_TOPIC" \ + }' \ + localhost:8008/_matrix/client/v3/pushers/set +``` + +repeat the first query and you'll see both of these listed. to delete the new pusher, repeat the above `curl` command with `kind` set to `null`. + +anyway, put your phone to sleep, have someone send you a message that Synapse would alert you on, and now your phone should awake! + + +### Prosody (XMPP) ntfy integration + +Prosody has [mod_cloud_notify](https://modules.prosody.im/mod_cloud_notify) and [XEP-0357](https://xmpp.org/extensions/xep-0357.html), but at the time of writing client support is wanting. easier is to hack it in server-side. + +Prosody has a Lua-based module system, so we can just author our own `mod_ntfy_push`, drop it in the modules directory, and then import it: + +```nix +services.prosody.extraPluginsPath = [ ./folder/containing/mod_ntfy_push ]; +services.prosody.extraModules = [ "ntfy_push" ]; +services.prosody.extraConfig = '' + ntfy_endpoint = "https://MY.NTFY.HOST/TEST_WOWLAN_TOPIC" +''; + +TODO: link `mod_ntfy_push.lua` here +``` + +i've only authored this module to alert me on jingle calls. one could presumably alert on DMs, MUC messages, or anything more particular by finding the right Prosody hooks (mod_cloud_notify may be an ok guide for that). + + +### Pinephone Wowlan Race Condition + +