diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 15bb8f87f..85a04a665 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -28,11 +28,17 @@ jobs: echo "[env.production]" >> wrangler.toml echo "kv_namespaces = [{binding=\"KV_STATUS_PAGE\", id=\"${KV_NAMESPACE_ID}\"}]" >> wrangler.toml [ -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 + [ -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 + [ -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 postCommands: | yarn kv-gc secrets: | SECRET_SLACK_WEBHOOK_URL + SECRET_TELEGRAM_API_TOKEN + SECRET_TELEGRAM_CHAT_ID environment: production env: CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} SECRET_SLACK_WEBHOOK_URL: ${{secrets.SECRET_SLACK_WEBHOOK_URL}} + SECRET_TELEGRAM_API_TOKEN: ${{secrets.SECRET_TELEGRAM_API_TOKEN}} + SECRET_TELEGRAM_CHAT_ID: ${{secrets.SECRET_TELEGRAM_CHAT_ID}} diff --git a/README.md b/README.md index dfed64161..6db6f2861 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,17 @@ You can either deploy with **Cloudflare Deploy Button** using GitHub Actions or - e.g. `status-page.eidam.dev/*` _\(make sure you include `/*` as the Worker also serve static files\)_ 8. _\(optional\)_ Edit [wrangler.toml](./wrangler.toml) to adjust Worker settings or CRON Trigger schedule, especially if you are on [Workers Free plan](#workers-kv-free-tier) +### Telegram notifications + +To enable telegram notifications, you'll need to take a few additional steps. + +1. [Create a new Bot](https://core.telegram.org/bots#creating-a-new-bot) +2. Set the api token you received when creating the bot as content of the `SECRET_TELEGRAM_API_TOKEN` secret in your github repository. +3. Send a message to the bot from the telegram account which should receive the alerts (Something more than `/start`) +4. Get the chat id with `curl https://api.telegram.org/bot/getUpdates | jq '.result[0] .message .chat .id'` +5. Set the retrieved chat id in the `SECRET_TELEGRAM_CHAT_ID` secret variable +6. Redeploy the status page using the github action + ### Deploy on your own You can clone the repository yourself and use Wrangler CLI to develop/deploy, extra list of things you need to take care of: diff --git a/src/functions/cronTrigger.js b/src/functions/cronTrigger.js index e370d2ed1..f12d98551 100644 --- a/src/functions/cronTrigger.js +++ b/src/functions/cronTrigger.js @@ -2,6 +2,7 @@ import config from '../../config.yaml' import { notifySlack, + notifyTelegram, getCheckLocation, getKVMonitors, setKVMonitors, @@ -76,6 +77,15 @@ export async function processCronTrigger(event) { event.waitUntil(notifySlack(monitor, monitorOperational)) } + // Send Telegram message on monitor change + if ( + monitorStatusChanged + && typeof SECRET_TELEGRAM_API_TOKEN !== 'undefined' && SECRET_TELEGRAM_API_TOKEN !== 'default-gh-action-secret' + && typeof SECRET_TELEGRAM_CHAT_ID !== 'undefined' && SECRET_TELEGRAM_CHAT_ID !== 'default-gh-action-secret' + ) { + event.waitUntil(notifyTelegram(monitor, monitorOperational)) + } + // make sure checkDay exists in checks in cases when needed if ( (config.settings.collectResponseTimes || !monitorOperational) && diff --git a/src/functions/helpers.js b/src/functions/helpers.js index 74cd113e0..812c32bcb 100644 --- a/src/functions/helpers.js +++ b/src/functions/helpers.js @@ -13,6 +13,12 @@ export async function setKVMonitors(data) { return setKV(kvDataKey, JSON.stringify(data)) } +const getOperationalLabel = operational => { + return operational + ? config.settings.monitorLabelOperational + : config.settings.monitorLabelNotOperational +} + export async function setKV(key, value, metadata, expirationTtl) { return KV_STATUS_PAGE.put(key, value, { metadata, expirationTtl }) } @@ -27,11 +33,7 @@ export async function notifySlack(monitor, operational) { type: 'section', text: { type: 'mrkdwn', - text: `Monitor *${monitor.name}* changed status to *${ - operational - ? config.settings.monitorLabelOperational - : config.settings.monitorLabelNotOperational - }*`, + text: `Monitor *${monitor.name}* changed status to *${getOperationalLabel(operational)}*`, }, }, { @@ -58,6 +60,22 @@ export async function notifySlack(monitor, operational) { }) } +export async function notifyTelegram(monitor, operational) { + const text = `Monitor *${monitor.name.replace('-', '\\-')}* changed status to *${getOperationalLabel(operational)}* + ${operational ? '✅' : '❌'} \`${monitor.method ? monitor.method : "GET"} ${monitor.url}\` \\- 👀 [Status Page](${config.settings.url})` + + const payload = new FormData() + payload.append('chat_id', SECRET_TELEGRAM_CHAT_ID) + payload.append('parse_mode', 'MarkdownV2') + payload.append('text', text) + + const telegramUrl = `https://api.telegram.org/bot${SECRET_TELEGRAM_API_TOKEN}/sendMessage` + return fetch(telegramUrl, { + body: payload, + method: 'POST', + }) +} + export function useKeyPress(targetKey) { const [keyPressed, setKeyPressed] = useState(false)