#!/usr/bin/env python3 """ Gateway Stop Handler - Sends notification when Gateway stops. Notifies only on each operation's origin channel. """ import sys import json import traceback from datetime import datetime, timezone from pathlib import Path from collections import defaultdict sys.path.insert(0, str(Path(__file__).parent)) def log(msg, level="INFO"): timestamp = datetime.now(timezone.utc).isoformat() line = f"[{timestamp}] [{level}] {msg}\n" try: print(line, flush=True) except: pass try: with open("/tmp/gateway_stop_handler.log", "a") as f: f.write(line) except: pass def main(): log("=== Gateway Stop Handler Started ===") try: from notify import send_notification log("notify module imported successfully") except Exception as e: log(f"Failed to import notify: {e}", "ERROR") return 0 try: from state_manager import OperationState log("state_manager imported successfully") except Exception as e: log(f"Failed to import state_manager: {e}", "ERROR") OperationState = None # Get interrupted operations interrupted = [] if OperationState: try: interrupted = OperationState.list_interrupted() log(f"Found {len(interrupted)} interrupted operation(s)") except Exception as e: log(f"Failed to list interrupted ops: {e}", "ERROR") # Group by origin channel and send notifications by_channel = defaultdict(list) for op in interrupted: ch = op.get('channel') if ch: by_channel[ch].append(op) for channel, ops in by_channel.items(): try: op_count = len(ops) message = f"⚠️ **Gateway STOPPED** — Operations Halted\n\n" message += f"📋 {op_count} operation(s) interrupted:\n" for op in ops[:5]: message += f"• `{op.get('agent_name', 'unknown')}`: {op.get('description', 'No description')}\n" if op_count > 5: message += f"• ... and {op_count - 5} more\n" message += f"\n⏱️ Stopped at: " # Use appropriate mention for the channel if channel.startswith("telegram:"): mention = "Julian" else: mention = ops[0].get('notify_user', 'taro83') send_notification(channel, message, mention=mention) log(f"Sent stop notification to {channel} for {op_count} operation(s)") except Exception as e: log(f"Failed to send to {channel}: {e}", "ERROR") # Save marker file try: marker_file = Path("/tmp/gateway_was_stopped") with open(marker_file, 'w') as f: json.dump({ "stopped_at": datetime.now(timezone.utc).isoformat(), "interrupted_count": len(interrupted), "interrupted_ops": [op.get('operation_id', 'unknown') for op in interrupted] }, f) log("Stop marker saved") except Exception as e: log(f"Failed to save marker: {e}", "ERROR") log("=== Gateway Stop Handler Complete ===") return 0 if __name__ == "__main__": sys.exit(main())