Files
PolyWeather/scripts/alertmanager_telegram_relay.py
T
2026-04-02 23:30:52 +08:00

108 lines
3.3 KiB
Python

from __future__ import annotations
import json
import os
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Any, Dict, List
import requests
def _chat_ids() -> List[str]:
raw = (
os.getenv("POLYWEATHER_MONITORING_ALERT_CHAT_IDS")
or os.getenv("TELEGRAM_CHAT_IDS")
or os.getenv("TELEGRAM_CHAT_ID")
or ""
)
return [item.strip() for item in raw.split(",") if item.strip()]
def _format_alerts(payload: Dict[str, Any]) -> str:
alerts = payload.get("alerts") or []
if not isinstance(alerts, list) or not alerts:
return "PolyWeather monitoring received an empty alert payload."
lines = ["PolyWeather monitoring alert"]
for alert in alerts[:10]:
if not isinstance(alert, dict):
continue
status = str(alert.get("status") or "unknown").upper()
labels = alert.get("labels") or {}
annotations = alert.get("annotations") or {}
alert_name = labels.get("alertname") or "unknown_alert"
severity = labels.get("severity") or "info"
summary = annotations.get("summary") or annotations.get("description") or ""
lines.append(f"- [{status}] {alert_name} ({severity})")
if summary:
lines.append(f" {summary}")
return "\n".join(lines)
def _send_telegram_message(text: str) -> None:
token = str(os.getenv("TELEGRAM_BOT_TOKEN") or "").strip()
chat_ids = _chat_ids()
if not token or not chat_ids:
return
url = f"https://api.telegram.org/bot{token}/sendMessage"
for chat_id in chat_ids:
try:
requests.post(
url,
json={
"chat_id": chat_id,
"text": text,
"disable_web_page_preview": True,
},
timeout=10,
).raise_for_status()
except Exception:
continue
def _send_alert_notifications(text: str) -> None:
_send_telegram_message(text)
class _Handler(BaseHTTPRequestHandler):
def do_GET(self) -> None: # noqa: N802
if self.path.rstrip("/") == "/healthz":
self.send_response(200)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.end_headers()
self.wfile.write(b'{"ok":true}')
return
self.send_error(404)
def do_POST(self) -> None: # noqa: N802
if self.path.rstrip("/") != "/alerts":
self.send_error(404)
return
length = int(self.headers.get("Content-Length", "0") or "0")
raw = self.rfile.read(length) if length > 0 else b"{}"
try:
payload = json.loads(raw.decode("utf-8"))
except Exception:
self.send_error(400, "invalid json")
return
if not isinstance(payload, dict):
self.send_error(400, "invalid payload")
return
_send_alert_notifications(_format_alerts(payload))
self.send_response(200)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.end_headers()
self.wfile.write(b'{"ok":true}')
def log_message(self, format: str, *args: object) -> None: # noqa: A003
return
def main() -> None:
port = 9099
server = HTTPServer(("0.0.0.0", port), _Handler)
server.serve_forever()
if __name__ == "__main__":
main()