#!/usr/bin/env python3 """Alertmanager webhook receiver that forwards alerts to Gotify.""" import json import os import sys from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.request import Request, urlopen from urllib.error import URLError GOTIFY_URL = os.environ["GOTIFY_URL"] DISASTER_TOKEN = os.environ["DISASTER_TOKEN"] WARNING_TOKEN = os.environ["WARNING_TOKEN"] DISASTER_PRIORITY = int(os.environ.get("DISASTER_PRIORITY", "8")) WARNING_PRIORITY = int(os.environ.get("WARNING_PRIORITY", "4")) SEVERITY_MAP = { "critical": (DISASTER_TOKEN, DISASTER_PRIORITY), "warning": (WARNING_TOKEN, WARNING_PRIORITY), } def send_gotify(token, title, message, priority): data = json.dumps({ "title": title, "message": message, "priority": priority, }).encode() req = Request( f"{GOTIFY_URL}/message?token={token}", data=data, headers={"Content-Type": "application/json"}, ) try: urlopen(req) except URLError as e: print(f"ERROR sending to Gotify: {e}", file=sys.stderr) class Handler(BaseHTTPRequestHandler): def do_POST(self): try: length = int(self.headers.get("Content-Length", 0)) body = json.loads(self.rfile.read(length)) except (json.JSONDecodeError, ValueError) as e: self.send_response(400) self.end_headers() self.wfile.write(f"Bad request: {e}".encode()) return for alert in body.get("alerts", []): severity = alert.get("labels", {}).get("severity", "warning") token, priority = SEVERITY_MAP.get(severity, SEVERITY_MAP["warning"]) status = alert.get("status", "firing") alertname = alert.get("labels", {}).get("alertname", "Unknown") summary = alert.get("annotations", {}).get("summary", "") prefix = "RESOLVED" if status == "resolved" else "FIRING" title = f"[{prefix}] {alertname}" message = summary or f"{alertname} is {status}" send_gotify(token, title, message, priority) print(f"Forwarded: {title} -> severity={severity} priority={priority}") self.send_response(200) self.end_headers() self.wfile.write(b"ok") def do_GET(self): if self.path == "/health": self.send_response(200) self.end_headers() self.wfile.write(b"ok") return self.send_response(404) self.end_headers() def log_message(self, format, *args): print(format % args) if __name__ == "__main__": port = int(os.environ.get("PORT", "8080")) server = HTTPServer(("0.0.0.0", port), Handler) print(f"Bridge listening on :{port}") server.serve_forever()