Guides

Common recipes for sending notifications from scripts, CI, and servers.

Notify when a script finishes

Append a curl call at the end of any shell script to get notified when it completes โ€” or when it fails.

#!/bin/bash
# your long-running script here
python train.py --epochs 50

# notify on success or failure
if [ $? -eq 0 ]; then
  curl -s -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET \
    -H 'Content-Type: application/json' \
    -d '{"title":"Training done","message":"Model reached 94% accuracy โœ…"}'
else
  curl -s -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET \
    -d 'Training failed โŒ'
fi

GitHub Actions

Add a notification step to any workflow. Store your secret in GitHub Actions secrets as NTF_SECRET.

# .github/workflows/deploy.yml
on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

      - name: Notify on success
        if: success()
        run: |
          curl -s -X POST "https://ntf-worker.buzagloidan.workers.dev/api/v1/${{ secrets.NTF_SECRET }}" \
            -H 'Content-Type: application/json' \
            -d '{"title":"Deploy succeeded","message":"${{ github.repository }} is live ๐Ÿš€"}'

      - name: Notify on failure
        if: failure()
        run: |
          curl -s -X POST "https://ntf-worker.buzagloidan.workers.dev/api/v1/${{ secrets.NTF_SECRET }}" \
            -d "Build failed on ${{ github.ref_name }}"

Python

Use the standard library โ€” no dependencies required.

import urllib.request, json

def notify(message, title=None, secret="YOUR_SECRET"):
    url = f"https://ntf-worker.buzagloidan.workers.dev/api/v1/{secret}"
    payload = {"message": message}
    if title:
        payload["title"] = title
    data = json.dumps(payload).encode()
    req = urllib.request.Request(url, data=data,
          headers={"Content-Type": "application/json"})
    urllib.request.urlopen(req)

# usage
notify("Scrape finished โ€” 4,201 records", title="Crawler")

Node.js

async function notify(message, title) {
  await fetch("https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ message, title }),
  });
}

// usage
notify("Job finished", "Cron");

Uptime monitor

Ping your webhook from a cron job to alert yourself when a service goes down.

#!/bin/bash
# crontab: */5 * * * * /path/to/check.sh

STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.example.com/health)

if [ "$STATUS" != "200" ]; then
  curl -s -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET \
    -H 'Content-Type: application/json' \
    -d "{\"title\":\"Down!\",\"message\":\"myapp returned $STATUS\",\"sound\":\"brrr\"}"
fi

Notification with a deep link

Tapping the notification opens a URL directly in Safari (or your app).

curl -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "PR merged",
    "message": "feat: dark mode support",
    "open_url": "https://github.com/you/repo/pull/42"
  }'

Notification with an image

Attach a remote image โ€” it appears expanded in the notification.

curl -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Chart updated",
    "message": "Weekly active users",
    "image_url": "https://charts.example.com/wau.png"
  }'

GET webhook (no request body)

Some services only support GET webhooks. Pass fields as query parameters.

curl "https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_SECRET?title=Alert&message=Disk+at+90%25"

Fan-out to all devices

Use your user secret (instead of the device secret) to send to every device on your iCloud account at once.

curl -X POST https://ntf-worker.buzagloidan.workers.dev/api/v1/YOUR_USER_SECRET \
  -d 'Sent to all your devices'

The response includes a sent count: {"success":true,"sent":2,"failures":0}