Skip to content

Commit c860f76

Browse files
Add ntfy webhook notifier
1 parent 7813ff9 commit c860f76

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

.github/workflows/deploy.yml

+9
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,28 @@ jobs:
3333
echo "kv_namespaces = [{binding=\"KV_STATUS_PAGE\", id=\"${KV_NAMESPACE_ID}\"}]" >> wrangler.toml
3434
[ -z "$SECRET_SLACK_WEBHOOK_URL" ] && echo "Secret SECRET_SLACK_WEBHOOK_URL not set, creating dummy one..." && SECRET_SLACK_WEBHOOK_URL="default-gh-action-secret" || true
3535
[ -z "$SECRET_TELEGRAM_API_TOKEN" ] && echo "Secret SECRET_TELEGRAM_API_TOKEN not set, creating dummy one..." && SECRET_TELEGRAM_API_TOKEN="default-gh-action-secret" || true
36+
[ -z "$SECRET_NTFY_WEBHOOK_URL" ] && echo "Secret SECRET_NTFY_WEBHOOK_URL not set, creating dummy one..." && SECRET_NTFY_WEBHOOK_URL="default-gh-action-secret" || true
37+
[ -z "$SECRET_NTFY_USERNAME" ] && echo "Secret SECRET_NTFY_USERNAME not set, creating dummy one..." && SECRET_NTFY_USERNAME="default-gh-action-secret" || true
38+
[ -z "$SECRET_NTFY_PASSWORD" ] && echo "Secret SECRET_NTFY_PASSWORD not set, creating dummy one..." && SECRET_NTFY_PASSWORD="default-gh-action-secret" || true
3639
[ -z "$SECRET_TELEGRAM_CHAT_ID" ] && echo "Secret SECRET_TELEGRAM_CHAT_ID not set, creating dummy one..." && SECRET_TELEGRAM_CHAT_ID="default-gh-action-secret" || true
3740
[ -z "$SECRET_DISCORD_WEBHOOK_URL" ] && echo "Secret SECRET_DISCORD_WEBHOOK_URL not set, creating dummy one..." && SECRET_DISCORD_WEBHOOK_URL="default-gh-action-secret" || true
3841
postCommands: |
3942
yarn kv-gc
4043
secrets: |
4144
SECRET_SLACK_WEBHOOK_URL
4245
SECRET_TELEGRAM_API_TOKEN
46+
SECRET_NTFY_WEBHOOK_URL
47+
SECRET_NTFY_USERNAME
48+
SECRET_NTFY_PASSWORD
4349
SECRET_TELEGRAM_CHAT_ID
4450
SECRET_DISCORD_WEBHOOK_URL
4551
environment: production
4652
env:
4753
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
4854
SECRET_SLACK_WEBHOOK_URL: ${{secrets.SECRET_SLACK_WEBHOOK_URL}}
4955
SECRET_TELEGRAM_API_TOKEN: ${{secrets.SECRET_TELEGRAM_API_TOKEN}}
56+
SECRET_NTFY_WEBHOOK_URL: ${{secrets.SECRET_NTFY_WEBHOOK_URL}}
57+
SECRET_NTFY_USERNAME: ${{secrets.SECRET_NTFY_USERNAME}}
58+
SECRET_NTFY_PASSWORD: ${{secrets.SECRET_NTFY_PASSWORD}}
5059
SECRET_TELEGRAM_CHAT_ID: ${{secrets.SECRET_TELEGRAM_CHAT_ID}}
5160
SECRET_DISCORD_WEBHOOK_URL: ${{secrets.SECRET_DISCORD_WEBHOOK_URL}}

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Also, prepare the following secrets
2020
- Cloudflare API token with `Edit Cloudflare Workers` permissions
2121
- Slack incoming webhook \(optional\)
2222
- Discord incoming webhook \(optional\)
23+
- Ntfy incoming webhook \(optional\)
24+
- Ntfy username \(optional\)
25+
- Ntfy password \(optional\)
2326

2427
## Getting started
2528

@@ -42,6 +45,15 @@ You can either deploy with **Cloudflare Deploy Button** using GitHub Actions or
4245

4346
- Name: SECRET_DISCORD_WEBHOOK_URL (optional)
4447
- Value: your-discord-webhook-url
48+
49+
- Name: SECRET_NTFY_WEBHOOK_URL (optional)
50+
- Value: your-ntfy-webhook-url
51+
52+
- Name: SECRET_NTFY_USERNAME (optional)
53+
- Value: your-ntfy-username
54+
55+
- Name: SECRET_NTFY_PASSWORD (optional)
56+
- Value: your-ntfy-password
4557
```
4658
4759
3. Navigate to the **Actions** settings in your repository and enable them
@@ -54,6 +66,7 @@ You can either deploy with **Cloudflare Deploy Button** using GitHub Actions or
5466
logo: logo-192x192.png # image in ./public/ folder
5567
daysInHistogram: 90 # number of days you want to display in histogram
5668
collectResponseTimes: false # experimental feature, enable only for <5 monitors or on paid plans
69+
ntfyPriority: 'urgent' # priority for ntfy notifications
5770

5871
# configurable texts across the status page
5972
allmonitorsOperational: 'All Systems Operational'
@@ -102,6 +115,9 @@ You can clone the repository yourself and use Wrangler CLI to develop/deploy, ex
102115
- create Worker secrets _\(optional\)_
103116
- `SECRET_SLACK_WEBHOOK_URL`
104117
- `SECRET_DISCORD_WEBHOOK_URL`
118+
- `SECRET_NTFY_WEBHOOK_URL`
119+
- `SECRET_NTFY_USERNAME`
120+
- `SECRET_NTFY_PASSWORD`
105121

106122
## Workers KV free tier
107123

config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ settings:
44
logo: logo-192x192.png # image in ./public/ folder
55
daysInHistogram: 90 # number of days you want to display in histogram
66
collectResponseTimes: true # collects avg response times from CRON locations
7+
ntfyPriority: 'urgent'
78

89
allmonitorsOperational: 'All Systems Operational'
910
notAllmonitorsOperational: 'Not All Systems Operational'

src/functions/cronTrigger.js

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getKVMonitors,
88
setKVMonitors,
99
notifyDiscord,
10+
notifyNtfy
1011
} from './helpers'
1112

1213
function getDate() {
@@ -89,6 +90,15 @@ export async function processCronTrigger(event) {
8990
event.waitUntil(notifyTelegram(monitor, monitorOperational))
9091
}
9192

93+
// Send ntfy message on monitor change
94+
if (
95+
monitorStatusChanged &&
96+
typeof SECRET_NTFY_WEBHOOK_URL !== 'undefined' &&
97+
SECRET_NTFY_WEBHOOK_URL !== 'default-gh-action-secret'
98+
) {
99+
event.waitUntil(notifyNtfy(monitor, monitorOperational))
100+
}
101+
92102
// Send Discord message on monitor change
93103
if (
94104
monitorStatusChanged &&

src/functions/helpers.js

+25
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,32 @@ export async function notifyTelegram(monitor, operational) {
8080
const telegramUrl = `https://api.telegram.org/bot${SECRET_TELEGRAM_API_TOKEN}/sendMessage`
8181
return fetch(telegramUrl, {
8282
body: payload,
83+
method: 'POST'
84+
})
85+
}
86+
87+
export async function notifyNtfy(monitor, operational) {
88+
const text = `${monitor.method ? monitor.method : 'GET'} ${
89+
monitor.url
90+
}`
91+
const headers = {
92+
'Title': `Monitor ${monitor.name} changed status to ${getOperationalLabel(operational)} ${operational ? '✅' : '❌'}`,
93+
'Priority': config.settings.ntfyPriority,
94+
'Click': `${config.settings.url}`,
95+
'Tags': 'status-page'
96+
}
97+
98+
if (typeof SECRET_NTFY_USERNAME !== 'undefined' &&
99+
SECRET_NTFY_USERNAME !== 'default-gh-action-secret' &&
100+
typeof SECRET_NTFY_PASSWORD !== 'undefined' &&
101+
SECRET_NTFY_PASSWORD !== 'default-gh-action-secret') {
102+
headers.authorization = `Basic ${Buffer.from(`${SECRET_NTFY_USERNAME}:${SECRET_NTFY_PASSWORD}`).toString('base64')}`
103+
}
104+
105+
fetch(SECRET_NTFY_WEBHOOK_URL, {
106+
body: text,
83107
method: 'POST',
108+
headers
84109
})
85110
}
86111

0 commit comments

Comments
 (0)