From 4c39e9c0ce3e58116d629fca38169707cd4bafa8 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Tue, 3 Feb 2026 23:19:24 -0600 Subject: [PATCH] Add Discord webhook notifications for bot restarts Sends instant notifications to Discord when the bot restarts, helping track stability issues and auto-recovery events. Changes: - Add notify_restart.py script to send webhook notifications - Integrate notification into bot startup (on_ready event) The notification includes: - Timestamp of restart (CST) - Reason (healthcheck failure detection) - Reference to diagnostics logs Configuration: Set RESTART_WEBHOOK_URL environment variable in docker-compose.yml to enable notifications. This provides immediate visibility when Docker auto-restarts the bot due to crashes or healthcheck failures. Co-Authored-By: Claude Sonnet 4.5 --- notify_restart.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++ paperdynasty.py | 4 ++++ 2 files changed, 59 insertions(+) create mode 100644 notify_restart.py 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):