#!/bin/bash # notify.sh — Centralized notification dispatcher # Usage: notify.sh [OPTIONS] "message" # # Options: # -t TITLE Title (default: "forge alert") # -p PRIORITY 1-5 (default: 3). 1=min, 3=default, 5=urgent # -T TAGS Comma-separated ntfy tag/emoji shortcodes (default: "bell") # -c CHANNEL Target channel: forge (default), inou, dashboard, all # -u Urgent mode: priority 5 + "rotating_light" tag # # Examples: # notify.sh "Disk usage at 87%" # notify.sh -t "K2 Killed" -p 4 -T "warning,robot" "Runaway session cleared" # notify.sh -c inou -t "inou error" "API returned 500" # notify.sh -c all "Critical: forge unreachable" set -euo pipefail # ── Config ──────────────────────────────────────────────────────────────────── NTFY_URL="https://ntfy.inou.com" NTFY_TOKEN="tk_k120jegay3lugeqbr9fmpuxdqmzx5" DASHBOARD_URL="http://localhost:9200/api/news" TOPIC_FORGE="forge-alerts" TOPIC_INOU="inou-alerts" # ── Defaults ────────────────────────────────────────────────────────────────── TITLE="forge alert" PRIORITY=3 TAGS="bell" CHANNEL="forge" URGENT=0 # ── Parse args ──────────────────────────────────────────────────────────────── while getopts ":t:p:T:c:u" opt; do case $opt in t) TITLE="$OPTARG" ;; p) PRIORITY="$OPTARG" ;; T) TAGS="$OPTARG" ;; c) CHANNEL="$OPTARG" ;; u) URGENT=1 ;; *) echo "Unknown option: -$OPTARG" >&2; exit 1 ;; esac done shift $((OPTIND - 1)) MESSAGE="${1:-}" if [ -z "$MESSAGE" ]; then echo "Usage: notify.sh [OPTIONS] \"message\"" >&2 exit 1 fi if [ "$URGENT" -eq 1 ]; then PRIORITY=5 TAGS="rotating_light" fi # ── Send to ntfy ────────────────────────────────────────────────────────────── ntfy_send() { local topic="$1" curl -s "$NTFY_URL/$topic" \ -H "Authorization: Bearer $NTFY_TOKEN" \ -H "Title: $TITLE" \ -H "Priority: $PRIORITY" \ -H "Tags: $TAGS" \ -H "Markdown: yes" \ -d "$MESSAGE" \ > /dev/null } # ── Send to dashboard news ──────────────────────────────────────────────────── dashboard_send() { # Map priority to dashboard type local type="info" [ "$PRIORITY" -ge 4 ] && type="warning" [ "$PRIORITY" -ge 5 ] && type="error" curl -s -X POST "$DASHBOARD_URL" \ -H "Content-Type: application/json" \ -d "{\"title\":\"$TITLE\",\"body\":\"$MESSAGE\",\"type\":\"$type\",\"source\":\"notify\"}" \ > /dev/null } # ── Dispatch ────────────────────────────────────────────────────────────────── case "$CHANNEL" in forge) ntfy_send "$TOPIC_FORGE" ;; inou) ntfy_send "$TOPIC_INOU" ;; dashboard) dashboard_send ;; all) ntfy_send "$TOPIC_FORGE" ntfy_send "$TOPIC_INOU" dashboard_send ;; *) echo "Unknown channel: $CHANNEL (forge|inou|dashboard|all)" >&2 exit 1 ;; esac exit 0