clawd/scripts/notify.sh

108 lines
3.7 KiB
Bash
Executable File

#!/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