diff --git a/notify_restart.py b/notify_restart.py new file mode 100644 index 0000000..5412252 --- /dev/null +++ b/notify_restart.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +Notify admin channel when bot restarts due to healthcheck failure. +Uses Discord webhook for instant notification. +""" + +import os +import urllib.request +import json +from datetime import datetime + + +def send_restart_notification(): + """Send notification to Discord via webhook.""" + webhook_url = os.getenv("RESTART_WEBHOOK_URL") + + if not webhook_url: + print("No RESTART_WEBHOOK_URL configured, skipping notification") + return False + + try: + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S CST") + + data = { + "content": ( + f"**Paper Dynasty Bot Auto-Restarted** at {timestamp}\n\n" + "Healthcheck detected bot was offline/frozen. " + "Bot has been automatically restarted.\n\n" + "Check `/logs/restart_diagnostics.log` for details." + ), + "username": "Paper Dynasty Monitor", + } + + req = urllib.request.Request( + webhook_url, + data=json.dumps(data).encode("utf-8"), + headers={"Content-Type": "application/json"}, + ) + + response = urllib.request.urlopen(req, timeout=5) + + if response.status == 204: + print(f"Restart notification sent successfully at {timestamp}") + return True + else: + print(f"Webhook returned status {response.status}") + return False + + except Exception as e: + print(f"Failed to send restart notification: {e}") + return False + + +if __name__ == "__main__": + send_restart_notification() diff --git a/paperdynasty.py b/paperdynasty.py index 1d24e13..c82b2c2 100644 --- a/paperdynasty.py +++ b/paperdynasty.py @@ -9,6 +9,7 @@ from discord.ext import commands from in_game.gameplay_models import create_db_and_tables from health_server import run_health_server +from notify_restart import send_restart_notification raw_log_level = os.getenv('LOG_LEVEL') if raw_log_level == 'DEBUG': @@ -70,6 +71,9 @@ async def on_ready(): logger.info(bot.user.name) logger.info(bot.user.id) + # Send restart notification if configured + send_restart_notification() + @bot.tree.error async def on_app_command_error(interaction: discord.Interaction, error: discord.app_commands.AppCommandError):