alert_relay.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python3
  2. """HyperDX alert-webhook → Telegram relay (ohmu).
  3. Võtab vastu HyperDX "generic" webhook POST-i ja saadab sisu Telegrami.
  4. Kasutab ainult standardteeki (ei vaja pip-pakette).
  5. Env: TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID (vaikimisi 5036685258)
  6. Kuulab: 0.0.0.0:9099
  7. """
  8. from __future__ import annotations
  9. import json
  10. import os
  11. import urllib.parse
  12. import urllib.request
  13. from http.server import BaseHTTPRequestHandler, HTTPServer
  14. TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "").strip()
  15. CHAT = os.environ.get("TELEGRAM_CHAT_ID", "5036685258")
  16. PORT = int(os.environ.get("PORT", "9099"))
  17. def send(text: str) -> None:
  18. if not TOKEN:
  19. print("[relay] TELEGRAM_BOT_TOKEN puudub", flush=True)
  20. return
  21. data = urllib.parse.urlencode({"chat_id": CHAT, "text": text[:4000], "parse_mode": "Markdown"}).encode()
  22. req = urllib.request.Request(f"https://api.telegram.org/bot{TOKEN}/sendMessage", data=data)
  23. try:
  24. with urllib.request.urlopen(req, timeout=20) as r:
  25. r.read()
  26. except Exception as e: # noqa: BLE001
  27. print("[relay] Telegram viga:", str(e)[:200], flush=True)
  28. def format_msg(data: dict) -> str:
  29. def pick(*keys):
  30. for k in keys:
  31. v = data.get(k) or (data.get("alert") or {}).get(k)
  32. if v not in (None, ""):
  33. return v
  34. return None
  35. name = pick("name", "alertName", "title") or "HyperDX alert"
  36. state = pick("state", "status", "event") or "?"
  37. icon = {"ALERT": "🔴", "alert": "🔴", "RESOLVED": "✅", "resolved": "✅", "OK": "✅"}.get(str(state), "⚠️")
  38. lines = [f"{icon} *{name}*", f"Seis: `{state}`"]
  39. msg = pick("message", "note", "description")
  40. if msg:
  41. lines.append(str(msg)[:800])
  42. if not msg:
  43. lines.append("```\n" + json.dumps(data, ensure_ascii=False)[:1200] + "\n```")
  44. return "\n".join(lines)
  45. class H(BaseHTTPRequestHandler):
  46. def do_POST(self): # noqa: N802
  47. n = int(self.headers.get("Content-Length", "0") or 0)
  48. raw = self.rfile.read(n) if n else b"{}"
  49. try:
  50. data = json.loads(raw or b"{}")
  51. except Exception: # noqa: BLE001
  52. data = {"message": raw.decode("utf-8", "replace")[:1000]}
  53. send(format_msg(data if isinstance(data, dict) else {"message": str(data)}))
  54. self.send_response(200)
  55. self.send_header("Content-Type", "application/json")
  56. self.end_headers()
  57. self.wfile.write(b'{"ok":true}')
  58. def do_GET(self): # noqa: N802
  59. self.send_response(200)
  60. self.end_headers()
  61. self.wfile.write(b"alert-relay ok")
  62. def log_message(self, *args): # vaikimisi logi maha
  63. return
  64. if __name__ == "__main__":
  65. print(f"[relay] kuulan :{PORT} -> Telegram {CHAT}", flush=True)
  66. HTTPServer(("0.0.0.0", PORT), H).serve_forever()