Send Free Push Notifications from Python and Bash Scripts Using ntfy.sh

AshAsh
5 min read

When I started working on automation tasks, email notifications seemed like the easiest way to stay updated. However, managing email authentication and dealing with lengthy code quickly became complicated. The notifications also felt too generic for task updates, and they required a lot of extra setup. This made it clear that there was a need for a simpler, more efficient solution. Wouldn’t it be nice if we could get phone notifications instead of SMS or email, in addition to desktop notifications? And even better, what if all of this was free? That's where ntfy came in.

ntfy (pronounced "notify") is a lightweight, simple-to-use push notification system that can easily send messages to our phone or computer without the complications of emails.

What Is a Channel?

In ntfy, messages are sent to a channel, which is just a topic name.

We can name our channel anything we like, such as test-backups or build-notify. Then, we can view or subscribe to it using a browser or the ntfy mobile app. The only thing to keep in mind is that, since creating and subscribing to a generic channel doesn’t require an account, the channel name must be unique. If we want to ensure that no one else can access it, we should choose a name that is difficult for others to guess.

For example, here is a sample URL to access a channel in a web browser:

https://ntfy.sh/test-automation

Send Notifications from Python

  1. Simple Notification

When running automation scripts, our main aim is to get notifications about task completion or errors. To send a basic notification from Python, use this single line of code:

import requests
requests.post("https://ntfy.sh/test-automation", data="Script completed")
  1. Add a Title

We can add a title to our message, which will appear in bold in the notification. Here’s how we can add a title:

import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed", headers={"Title": "Backup Status"})
  1. Send Priority Messages

Higher priority messages appear more strikingly. The priority can range from 1 (low) to 5 (high). Here's an example of how to set a high priority:

import requests
requests.post("https://ntfy.sh/test-automation", data="Disk space low", headers={"Title": "Alert", "Priority": "5"})
  1. Email Notifications

ntfy supports forwarding notifications as emails by adding the "Email" header with a valid recipient address. This is helpful when we want certain alerts to persist longer or also reach our inbox. Due to lack of authentication, email sending is rate-limited, allowing up to 16 emails per IP address, followed by one per hour. The sender’s IP is included in the email body to prevent abuse.

import requests
requests.post("https://ntfy.sh/test-automation", data="Disk space on server-1 has dropped below 10%", headers={"Email": "myemail@example.com", "Tags": "warning,disk-monitor", "Priority": "high"})

We can include URLs in our message and they will automatically become clickable in the notification:

import requests
requests.post("https://ntfy.sh/test-automation", data="Check results: https://example.com/report")

We can attach external file links using the Attach header:

import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed successfully", headers={"Title": "Backup Completed", "Attach": "https://example.com/report.pdf"})
  1. Actual File Attachment

If we want to send an actual file (like a log or image) as an attachment, make sure to use a PUT request instead of POST, and include the filename in the headers. Here is how:

import requests
with open("log.txt", "rb") as f:
    requests.put("https://ntfy.sh/test-automation", data=f, headers={"Title": "Backup Completed", "Filename": "log.txt"})
  1. Add Emojis

We can tag our messages with emojis using the Tags header. Tags must be comma-separated. If a tag matches a known emoji shortcode, ntfy will automatically convert it into an emoji and prepend it to the title or message. Tags that don't match an emoji will still appear as labels beneath the notification. This is especially useful for marking different types of alerts or organizing our messages visually. Refer to the complete list of supported emojis and their shortcodes here.

import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed successfully", headers={"Tags": "heavy_check_mark,nightly-job"})
  1. Delayed Delivery

We can delay the delivery of messages and let ntfy send them at a later time. For this, we use the "In" header to specify a relative delay in seconds, minutes, or hours. For example "10s" for 10 seconds,"2m" for 2 minutes and "3h" for 3 hours.

We might think we can do the same thing with Python code that checks the target time in a loop and sends a notification when the time is right. But there is a reason to use ntfy instead. With Python, the script will stop and wait until the condition is met. But with ntfy, we can calculate the time difference between now and the target time, set a delayed notification, and keep the rest of the script running. The ntfy server will handle the waiting and send the notification at the right time. This makes the script simpler for us.

While ntfy also supports scheduling messages at an exact time using the "At" header, we have not covered that in this article to avoid complications arising from time zone differences. We are only using relative delays (In) for simplicity and predictability.

import requests
requests.post("https://ntfy.sh/test-automation", data="This message will be sent in 1 minute", headers={ "In": "1m" })
  1. Sending JSON Messages

Instead of plain text, we can send a JSON payload when we need to send multiple pieces of information together:

import requests
requests.post("https://ntfy.sh", json={"topic": "test-automation", "message": "Job failed", "title": "Job Status", "priority": 5})

Send Notifications from Bash

  1. Simple Notification

curl -d "Script completed" https://ntfy.sh/test-automation
  1. Add a Title

curl -d "Backup completed" -H "Title: Backup Status" https://ntfy.sh/test-automation
  1. Send Priority Messages

curl -d "Disk space low" -H "Title: Alert" -H "Priority: 5" https://ntfy.sh/test-automation
  1. Email Notifications

curl -d "Disk space on server-1 has dropped below 10%"   -H "Email: myemail@example.com" -H "Tags: warning,disk-monitor" -H "Priority: high" ntfy.sh/test-automation
curl -d "Check results: https://example.com/report" https://ntfy.sh/test-automation
curl -d "Backup completed successfully" -H "Title: Backup Completed" -H "Attach: https://example.com/report.pdf" https://ntfy.sh/test-automation
  1. Actual File Attachment

curl -T log.txt -H "Title: Backup Completed" -H "Filename: log.txt" https://ntfy.sh/test-automation
  1. Add Emojis

curl -d "Backup completed successfully" -H "Tags: heavy_check_mark,nightly-job" https://ntfy.sh/test-automation
  1. Delayed Delivery

curl -d "This message will be sent in 1 minute" -H "In: 1m" https://ntfy.sh/test-automation
  1. Sending JSON Messages

curl -H "Content-Type: application/json" -d '{"topic":"test-automation","message":"Job failed","title":"Job Status","priority":5}' https://ntfy.sh

For more details, check the official documentation here.

0
Subscribe to my newsletter

Read articles from Ash directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ash
Ash

DevOps Automation Engineer with around 7 years of experience in CI/CD pipeline automation, cloud deployments, and process optimization. Specializing in Harness CD, I have streamlined deployments, automated processes, reduced manual efforts, and improved release workflows.