Build the Script in Python
A’ight, time to get creative. We now know that the whole shenanigans work but don’t want to keep sending manual messages through the web interface. A short Python script is needed (or whatever programming language you prefer).
Technically, all this script does is behave like a webhook: It sends a request to the server with headers that contain all the information and, most importantly, the topic.
This is where Python comes into play. The only library you need to install via pip is requirements. I recommend, even for this small script, creating a virtual environment, switching into it and installing it for the chosen compiler:
# This is where I store my project
cd ~/Coding/Python/wife-water-reminder
# Creates a virtual environment
python3 -m venv venv
# Switches the current terminal session into this environment
source venv/bin/activate
# Install the required module in this venv
pip install requests
# Our script file
touch main.pyBashAfter this is done, we open main.py, which is where the code is located. Eventually, we want to run python3 main.py to trigger our script.
Again, here’s the method that sends everything to ntfy.sh1:
import requests
requests.post("https://ntfy.sh/wife-water-reminder",
data="You should drink some water now.",
headers={
"Title": "Water Reminder",
"Priority": "urgent",
"Tags": "warning,skull"
})PythonYou already see what goes on here: we post information to ntfy.sh, specifically to our topic, and tell it what to display via the data and header parameters. At this point, I’ll only link you to the official documentation; otherwise, I’ll end up writing a second one. In there, you can find out what keys headers take, what the format of the values is supposed to be, and so on.
Send as JSON
I personally prefer to send my request in Python in JSON format. It’s easier to read, in my opinion. An example might look like this (copied from the documentation):
requests.post("https://ntfy.sh/",
data=json.dumps({
"topic": "mytopic",
"message": "Disk space is low at 5.1 GB",
"title": "Low disk space alert",
"tags": ["warning","cd"],
"priority": 4,
"attach": "https://filesrv.lan/space.jpg",
"filename": "diskspace.jpg",
"click": "https://homecamera.lan/xasds1h2xsSsa/",
"actions": [{ "action": "view", "label": "Admin panel", "url": "https://filesrv.lan/admin" }]
})
)PythonIn the “Publish as JSON” section of the documentation, you’ll find a table listing all keys and their expected values. I don’t think there’s much more to say since it’s more or less self-explanatory by now.
One thing, though, you should keep in mind: compatibility. See the little icons following the line “Supported on”? Those show you what works on what OS and what doesn’t. iOS, for example, cannot display icons or images within the prompt. So, in that case, you’d better stick to simple emojis if you want some styling.
Additional Services
There’s quite a bit more than “just” sending notifications, but since this was our, or let’s say my, goal, I won’t go into the stuff talking about emails, attachments, and the like.
Instead, if you like the service as much as I do and want to show some gratitude despite being open source and basically free, be a good boy (or girl) and donate a few bucks to Philipp C. Heckel, the man behind this helpful tool. He says he prefers donations in Bitcoins, so here’s the address:
bc1q59nl3s92kqeqy37ccj3ks2pd6h8dvk85qajlhy
With that, I think we’re done for today. Oh, right, we missed a little thing.
Deploying your Script
Once we have the virtual environment running on our localhost and can trigger notifications, it’s time to upload it to your server so you can run the script via cron jobs at specific times and intervals. I do this via SSH:
- Create a GitLab/GitHub repository with the code (use this
.gitignoreto only commit the files that are needed) - Connect to my server via SSH
- Use
git cloneto download the repository onto my server - Briefly install it as seen in the section “Virtual Environment.”
Manually send a test push notification via python3 main.py while you’re within the virtual environment, and if everything works, you may set up a cron job to automate the whole thing for you. The format to run this script for my wife—meaning Mondays to Fridays, 09:30 to 17:30, no weekends—looks like this:
30 9-17 * * 1-5
Since cron jobs have been around for a while and are probably not part of the vibe coder stack, use a generator to create the correct format.
And if you want to have full control over everything this service does, well, then install it yourself on your server. There are many ways to do that, but I’m not going into that because you’re old enough to do this yourself. Hopefully. If you’re going the SSH route (installing the .deb file or use sudo apt install ntfy), I found MiniMax M2.1 to be a great model that balances out thinking and speed. When something goes wrong, just throw the terminal output at it, and you’ll be fine—unless it gives up and commits AI-suicide with rm -rf /.
Footnotes
- If you decide to self-host this service, you’ll need to make some changes. Check out this page on how to do that. ↩︎
