Ham Alerts on a deGoogled Phone

This blog has been a bit neglected the past few months because I fell down an amateur radio rabbit hole. I got my technician license in March, my General in April, and I'm taking my Extra test at the end of June. You can follow all my ham radio adventures on Mastodon.radio. My ham radio related code can be found on my ham radio GitLab repository

A big aspect of amateur radio is contacting people across the world. With a wire and a prayer, you can talk into a microphone and someone, somewhere, might hear you.

Making random contacts is fun, but you may want to make contacts with people you know or from specific countries. For that there is a service called Ham Alert. Ham Alert will send a notification to your phone if someone is on air.

Unfortunately for me, my phone is deGoogled and the Ham Alert app uses Google's push notification service. I can install the app, but I never see notifications. I needed another way to get notifications.

Ham Alert has a number of ways to get the alerts. There's the app, Threema, SMS via TextAnywhere, a telnet service, and POSTing to a URL. I don't need yet another chat app on my phone, so Threema is out. TextAnywhere is a paid service, so that is out. That leaves the telnet service and the URL destination.

Given that Ham Alert can make a POST request whenever an alert is triggered, I knew it would be pretty easy to integrate. I just need to write a web service to accept the JSON Ham Alert sends and forward that to something that will alert on my phone.

Ugh, I really didn't want to have to write an entire web service just to act on a single HTTP POST request. I have a VPS that I self-host some services on, but I didn't want to go through the rigmarole of packaging up the service and deploying it to my VPS.

NixOS modules have spoiled me where if there's not already a NixOS module for a service, I'm not going to bother. Setting up Cloudlog on my VPS was 13 lines of code.

What could I install on my VPS that would allow me to quickly accept JSON from Ham Alert and turn it into a notification? I once made an ESPHome current monitor that sent me a discord message whenever my washer or dryer stopped drawing current. I used Node Red for that.

Node Red, if you're unfamiliar, is a low-code platform for wiring hardware or software together. It is a browser-based visual programming tool. There's a NixOS module for Node Red, I can trivially deploy it to my VPS.

Next, I need a way to send notifications to my phone. My first instinct was to set up a Discord web hook, but those go to an entire server and I don't want to annoy my family with Ham Alerts. Eventually I found ntfy that is open source, has a NixOS module, and has an android app.

So I had the necessary parts to solve my problem. I have Node Red which can accept HTTP requests from Ham Alert, transform the Alert JSON, and make a request to ntfy to make a notification appear on my phone.

Configuring services in NixOS

To enable Node Red, I enable the service in my VPS's configuration.nix file.

In order to enable password authentication for Node Red, I needed to provide a settings file. In that settings file is the password hash for my admin account. I use Agenix to encrypt the settings file and store it in my git repo.

To enable ntfy, I do much of the same.

By default, the NixOS module configures ntfy wide open. I didn't want just anyone to be able to SPAM my phone, so I configured it with access control.

The NixOS module does not have a way to do this declaratively, so I ssh'd into the VPS and ran the ntfy user and nfty access commands to manually to set up the following policy.

user eric-phone (role: user, tier: none)  
- read-only access to topic ham-alerts  
user node-red (role: user, tier: none)  
- write-only access to topic ham-alerts  
user * (role: anonymous, tier: none)  
- no topic-specific permissions  
- no access to any (other) topics (server config)

Using the principle of least privilege, eric-phone can only read from topics, node-red can only publish to the ham-alerts topic. Each of the users have a unique password to prevent anyone from using them.

Developing the Node Red flow

The Node Red flow is pretty straight-forward. The first node is the http in node.
This defines a URL that Ham Alert will POST the alerts to. I can't password protect this URL because Ham Alert doesn't support that. I have to do my best to make the URL a secret by added a random string to the end of the URL. (Yes, that is not the URL is used, so don't try it)

The request body that Ham Alert sends looks like this:

The request body is parsed by the http in node and is placed in the msg.payload field of the node's output. Next I use the template node to format the alert JSON as text

This rendered text is set on the msg.payload value of the node's output.

The final step is to make an HTTP POST request to the ntfy ham-alerts topic. The msg.payload value from the template node is used as the request body. nfty sends that as the

The result of which shows up in my nfty app

Configuring Ham Alert

The final part of the project to configure Ham Alert. Under the destinations section, I scrolled down to the URL notifications section and put in the URL I used for the http in node.

This will post the alert JSON to that URL whenever a trigger has the URL action enabled.

Configuring the ntfy app

There are three things that I need to do in the ntfy app. I set the default server in the settings. I add the eric-phone user under Settings -> Manager users and then I subscribe to the ham-alerts topic.

Conclusion

Node Red proves again to be a very flexible platform to quickly hacking together a solution. Now that I have it on my VPS, I can use it for all kinds of integrations.

The ntfy service is a nice little service that lets me pretty trivially send notifications to my phone or in fact any application that needs near real-time message passing. I'm excited to find uses for it.

The configuration of my apps.ericcodes.io VPS is found at my GitLab