#!/usr/bin/env python3 """Send a Telegram status ping through the existing Hermes meeting-recording-status webhook. Used by the Claude refine step to notify Kai that a draft is ready, reusing the same signed channel that meeting-watch.py uses for 开始转录/转录完成. Usage: meeting-status-notify.py "" "" "" Silent no-op (exit 0) if the webhook/secret is unavailable — never block the pipeline. """ import hashlib import hmac import json import os import sys import urllib.request from pathlib import Path URL = os.environ.get("MEETING_STATUS_WEBHOOK_URL", "http://127.0.0.1:8644/webhooks/meeting-recording-status") ROUTE = os.environ.get("MEETING_STATUS_WEBHOOK_ROUTE", "meeting-recording-status") SUBSCRIPTIONS = Path(os.environ.get("MEETING_SUBSCRIPTIONS_FILE", str(Path.home() / ".hermes" / "webhook_subscriptions.json"))) def secret(): if os.environ.get("MEETING_STATUS_WEBHOOK_SECRET"): return os.environ["MEETING_STATUS_WEBHOOK_SECRET"] try: data = json.loads(SUBSCRIPTIONS.read_text(encoding="utf-8")) return str(data.get(ROUTE, {}).get("secret", "")) except Exception: return "" def main(): status = sys.argv[1] if len(sys.argv) > 1 else "通知" filename = sys.argv[2] if len(sys.argv) > 2 else "" detail = sys.argv[3] if len(sys.argv) > 3 else "" payload = json.dumps({"status": status, "filename": filename, "detail": detail}, ensure_ascii=False).encode("utf-8") headers = {"Content-Type": "application/json"} sec = secret() if sec and sec != "INSECURE_NO_AUTH": headers["X-Webhook-Signature"] = hmac.new(sec.encode(), payload, hashlib.sha256).hexdigest() try: req = urllib.request.Request(URL, data=payload, headers=headers, method="POST") with urllib.request.urlopen(req, timeout=10) as resp: print(f"status webhook -> {resp.status}") except Exception as exc: print(f"status webhook skipped: {exc}") if __name__ == "__main__": main()