Ever since thinking “that’s quite nifty”, I have the devil of a time spelling ntfy without transposing the ‘t’ and the ‘f’, but it’s called notify so the ‘t’ comes before the ‘f’. :-)

With ntfy I can send push notifications to a phone or desktop via a simple HTTP-based pub/sub service. Philipp C. Heckel created ntfy and open-sourced its components.

ntfy is the backend server (written in Golang), Android and iOS apps, and a desktop UI which runs in a Web browser. There’s also a command-line client – the same binary as the server.

Messages are published via either HTTP PUT or POST, and something as simple as this suffices to transmit a message. Note that there’s no access control on the public server so use your own server with access control or chose a topic which is hard to guess.

$ curl -d "Hola mundo" ntfy.sh/my-topic

Subscribing via the API is equally easy:

$ curl -s ntfy.sh/admin-alerts/json
{"id":"AQJQ0ThDMuda","time":1667123190,"event":"open","topic":"admin-alerts"}
{"id":"7osug0iTf31n","time":1667123207,"event":"message","topic":"admin-alerts","message":"deployment on alice is complete. 🐄","priority":1,"tags":["heavy_check_mark"]}
{"id":"by9EicvNYMsp","time":1667123235,"event":"keepalive","topic":"admin-alerts"}

All manner of features can be added to a message: priorities, tags, title, attachments, and messages can even contain an action to send a HTTP request from the client when an action button is tapped.

The CLI can also publish and subscribe, and a nifty feature is its ability to launch a command for each message received:

$ ntfy publish -p high --tags warning admin-alerts hola mundo
...
$ ntfy subscribe admin-alerts /usr/bin/myprog

The program gets environment variables passed to it:

id=f9T2bupNLjjR
m=hola mundo
message=hola mundo
NTFY_ID=f9T2bupNLjjR
NTFY_MESSAGE=hola mundo
NTFY_PRIORITY=4
NTFY_RAW={"id":"f9T2bupNLjjR","time":1667153184,"event":"message","topic":"admin-alerts","message":"hola mundo","priority":4,"tags":["warning"]}
NTFY_TAGS=warning
NTFY_TIME=1667153184
NTFY_TITLE=
NTFY_TOPIC=admin-alerts
p=4
prio=4
priority=4
raw={"id":"f9T2bupNLjjR","time":1667153184,"event":"message","topic":"admin-alerts","message":"hola mundo","priority":4,"tags":["warning"]}
t=
ta=warning
tag=warning
tags=warning
time=1667153184
title=
topic=admin-alerts

(I later found the documentation on the client.)

ntfy on iOS

Ansible

I was thinking about Ansible action plugins the other day and decided to implement one which notifies via ntfy. Why an action plugin and not a module? Because I’d expect notification to be emitted from the Ansible controller (also possible with a module delegated to it) so that’s how I did it. (Let me know if you prefer a module; we could do both.)

- ntfy:
     msg: "deployment on {{ inventory_hostname }} is complete. 🐄"

ansible-ntfy notifies ntfy.sh by default with a topic configured in a play var. Topic, URL, and additional publishing features can be configured in a dict passed as attrs:

- ntfy:
     topic: "admin-alerts"
     url: "https://nfty.sh"
     msg: "that's a wrap"
     attrs:
        tags: [ rotating_light, heavy_check_mark ]
        priority: 4
        actions:
           - action: view
             label: "Open Mastodon"
             url: "https://mastodon.social/@jpmens"

Aside from this Ansible module, there are lots of existing integrations.

ntfy is nifty. :-)

push, ansible, and notification :: 30 Oct 2022 :: e-mail