modificando mensajes

This commit is contained in:
Daniel Fernandez Sotolongo
2025-09-27 12:31:54 -04:00
parent 514c655746
commit 89cae3d090
2 changed files with 255 additions and 252 deletions

View File

@ -10,6 +10,8 @@ services:
environment:
- TZ=America/Havana
- PYTHONUNBUFFERED=1
# Pasa el nombre del host al contenedor del notificador
- WATCHTOWER_NOTIFICATIONS_HOSTNAME=Servidor-Easypanel
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:

View File

@ -1,23 +1,24 @@
#!/usr/bin/env python3
#watchtower_telegram_notifier.py
"""
Watchtower Telegram Notifier - Notificaciones personalizadas en español
Monitorea los logs de Watchtower y envía notificaciones detalladas a Telegram
Watchtower Telegram Notifier - Notificaciones personalizadas en español
Monitorea los logs de Watchtower y envía notificaciones detalladas a Telegram
"""
import docker
import requests
import time
import re
import os
from datetime import datetime
from threading import Thread
import logging
# Configuración
# Configuración
TELEGRAM_BOT_TOKEN = "7676713419:AAG-tfwzgrA9JaU5xNjvG5iBlFeZpz2ahiY"
TELEGRAM_CHAT_ID = "7940222048"
WATCHTOWER_CONTAINER_NAME = "watchtower"
HOSTNAME = "Servidor-Easypanel"
# Obtener el nombre del host de una variable de entorno, con un valor por defecto
HOSTNAME = os.environ.get("WATCHTOWER_NOTIFICATIONS_HOSTNAME", "Servidor-Easypanel")
# Configurar logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@ -31,7 +32,7 @@ class WatchtowerTelegramNotifier:
self.scan_in_progress = False
def send_telegram_message(self, message):
"""Envía mensaje a Telegram"""
"""Envía mensaje a Telegram"""
try:
payload = {
'chat_id': TELEGRAM_CHAT_ID,
@ -40,47 +41,47 @@ class WatchtowerTelegramNotifier:
}
response = requests.post(self.telegram_url, data=payload, timeout=10)
if response.status_code == 200:
logger.info("✅ Mensaje enviado a Telegram exitosamente")
logger.info(" Mensaje enviado a Telegram exitosamente")
return True
else:
logger.error(f"❌ Error enviando mensaje: {response.status_code}")
logger.error(f" Error enviando mensaje: {response.status_code}")
return False
except Exception as e:
logger.error(f"❌ Error conectando a Telegram: {e}")
logger.error(f" Error conectando a Telegram: {e}")
return False
def format_startup_message(self):
"""Mensaje de inicio del sistema"""
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = f"""🔄 <b>WATCHTOWER INICIADO</b>
message = f"""🔄 <b>WATCHTOWER INICIADO</b>
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
⚙️ <b>Estado:</b> Monitoreo activo
🕐 <b>Intervalo:</b> Cada 24 horas
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
⚙️ <b>Estado:</b> Monitoreo activo
🕐 <b>Intervalo:</b> Cada 24 horas
📋 <b>Contenedores monitoreados:</b>"""
📋 <b>Contenedores monitoreados:</b>"""
try:
containers = self.client.containers.list()
for container in containers:
if container.name != WATCHTOWER_CONTAINER_NAME:
status_emoji = "🟢" if container.status == "running" else "🔴"
status_emoji = "🟢" if container.status == "running" else "🔴"
message += f"\n{status_emoji} {container.name}"
except Exception as e:
logger.error(f"Error obteniendo contenedores: {e}")
message += "\n\n✅ <b>Sistema listo para detectar actualizaciones</b>"
message += "\n\n <b>Sistema listo para detectar actualizaciones</b>"
return message
def format_scan_start_message(self):
"""Mensaje cuando inicia un escaneo"""
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return f"""🔍 <b>ESCANEO DE ACTUALIZACIONES INICIADO</b>
return f"""🔍 <b>ESCANEO DE ACTUALIZACIONES INICIADO</b>
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
⏳ <b>Estado:</b> Verificando imágenes...
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
<b>Estado:</b> Verificando imágenes...
<i>Buscando actualizaciones disponibles...</i>"""
@ -89,47 +90,47 @@ class WatchtowerTelegramNotifier:
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if updated_containers:
message = f"""🎉 <b>ACTUALIZACIONES COMPLETADAS</b>
message = f"""🎉 <b>ACTUALIZACIONES COMPLETADAS</b>
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
<b>📥 ACTUALIZACIONES REALIZADAS:</b>"""
<b>📥 ACTUALIZACIONES REALIZADAS:</b>"""
for container_info in updated_containers:
message += f"\n✅ <b>{container_info['name']}</b>"
message += f"\n 📋 Imagen: <code>{container_info['image']}</code>"
message += f"\n <b>{container_info['name']}</b>"
message += f"\n   📋 Imagen: <code>{container_info['image']}</code>"
if container_info.get('old_image'):
message += f"\n 🔄 Desde: <code>{container_info['old_image']}</code>"
message += f"\n   🔄 Desde: <code>{container_info['old_image']}</code>"
unchanged = [c for c in checked_containers if c not in [u['name'] for u in updated_containers]]
if unchanged:
message += f"\n\n<b>ℹ️ SIN CAMBIOS:</b>"
message += f"\n\n<b> SIN CAMBIOS:</b>"
for container in unchanged:
message += f"\n🔘 {container}"
message += f"\n🔘 {container}"
message += f"\n\n🎯 <b>Total actualizados:</b> {len(updated_containers)}"
message += "\n✨ <b>¡Todos los servicios están actualizados!</b>"
message += f"\n\n🎯 <b>Total actualizados:</b> {len(updated_containers)}"
message += "\n <b>¡Todos los servicios están actualizados!</b>"
else:
message = f"""ℹ️ <b>VERIFICACIÓN COMPLETADA</b>
message = f""" <b>VERIFICACIÓN COMPLETADA</b>
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
🏠 <b>Servidor:</b> {HOSTNAME}
📅 <b>Fecha:</b> {now}
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
<b>📋 ESTADO:</b>"""
<b>📋 ESTADO:</b>"""
for container in checked_containers:
message += f"\n🔘 <b>{container}</b> - Sin actualizaciones"
message += f"\n🔘 <b>{container}</b> - Sin actualizaciones"
message += "\n\n✅ <b>Todos los contenedores están al día</b>"
message += "\n\n <b>Todos los contenedores están al día</b>"
return message
def parse_watchtower_logs(self, log_line):
"""Analiza líneas de log de Watchtower"""
"""Analiza líneas de log de Watchtower"""
log_line = log_line.strip()
# Detectar inicio de escaneo
@ -156,7 +157,7 @@ class WatchtowerTelegramNotifier:
'image': 'Detectando...',
'updated': True
}
logger.info(f"📦 Actualización detectada: {container_name}")
logger.info(f"📦 Actualización detectada: {container_name}")
break
# Detectar fin de proceso
@ -166,13 +167,13 @@ class WatchtowerTelegramNotifier:
self.scan_in_progress = False
def send_update_report(self):
"""Envía el reporte final de actualizaciones"""
"""Envía el reporte final de actualizaciones"""
try:
# Obtener lista actual de contenedores
containers = self.client.containers.list(all=True)
container_names = [c.name for c in containers if c.name != WATCHTOWER_CONTAINER_NAME]
# Completar información de contenedores actualizados
# Completar información de contenedores actualizados
updated_list = []
for container_name, info in self.container_updates.items():
try:
@ -188,16 +189,16 @@ class WatchtowerTelegramNotifier:
except Exception as e:
logger.error(f"Error generando reporte: {e}")
error_msg = f"❌ <b>Error generando reporte de actualizaciones</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}"
error_msg = f" <b>Error generando reporte de actualizaciones</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}"
self.send_telegram_message(error_msg)
def monitor_watchtower(self):
"""Monitorea logs de Watchtower en tiempo real"""
logger.info("🔍 Iniciando monitoreo de Watchtower...")
logger.info("🔍 Iniciando monitoreo de Watchtower...")
try:
container = self.client.containers.get(WATCHTOWER_CONTAINER_NAME)
logger.info(f"✅ Contenedor Watchtower encontrado: {container.id[:12]}")
logger.info(f" Contenedor Watchtower encontrado: {container.id[:12]}")
# Enviar mensaje de inicio
self.send_telegram_message(self.format_startup_message())
@ -214,38 +215,38 @@ class WatchtowerTelegramNotifier:
continue
except docker.errors.NotFound:
error_msg = f"❌ <b>ERROR: Contenedor Watchtower no encontrado</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Nombre esperado:</b> {WATCHTOWER_CONTAINER_NAME}"
error_msg = f" <b>ERROR: Contenedor Watchtower no encontrado</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Nombre esperado:</b> {WATCHTOWER_CONTAINER_NAME}"
self.send_telegram_message(error_msg)
logger.error("❌ Contenedor Watchtower no encontrado")
logger.error(" Contenedor Watchtower no encontrado")
except Exception as e:
error_msg = f"❌ <b>ERROR EN MONITOREO</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}"
error_msg = f" <b>ERROR EN MONITOREO</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}"
self.send_telegram_message(error_msg)
logger.error(f"❌ Error en monitoreo: {e}")
logger.error(f" Error en monitoreo: {e}")
def main():
logger.info("🚀 Iniciando Watchtower Telegram Notifier...")
logger.info("🚀 Iniciando Watchtower Telegram Notifier...")
notifier = WatchtowerTelegramNotifier()
# Verificar conexión a Telegram
test_message = f"🤖 <b>Bot de notificaciones iniciado</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n📅 <b>Fecha:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n✅ <b>Conexión establecida correctamente</b>"
# Verificar conexión a Telegram
test_message = f"🤖 <b>Bot de notificaciones iniciado</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n📅 <b>Fecha:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n <b>Conexión establecida correctamente</b>"
if notifier.send_telegram_message(test_message):
logger.info("✅ Conexión a Telegram verificada")
logger.info(" Conexión a Telegram verificada")
else:
logger.error("❌ Error de conexión a Telegram")
logger.error(" Error de conexión a Telegram")
return
# Iniciar monitoreo
try:
notifier.monitor_watchtower()
except KeyboardInterrupt:
logger.info("🛑 Monitoreo interrumpido por el usuario")
farewell_msg = f"👋 <b>Monitoreo detenido</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n📅 <b>Fecha:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n⚠️ <b>Bot desconectado</b>"
logger.info("🛑 Monitoreo interrumpido por el usuario")
farewell_msg = f"👋 <b>Monitoreo detenido</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n📅 <b>Fecha:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n⚠️ <b>Bot desconectado</b>"
notifier.send_telegram_message(farewell_msg)
except Exception as e:
logger.error(f"❌ Error fatal: {e}")
error_msg = f"💥 <b>ERROR FATAL EN BOT</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}\n\n🔄 <b>Reinicia el script</b>"
logger.error(f" Error fatal: {e}")
error_msg = f"💥 <b>ERROR FATAL EN BOT</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}\n\n🔄 <b>Reinicia el script</b>"
notifier.send_telegram_message(error_msg)
if __name__ == "__main__":