modificando mensajes
This commit is contained in:
@ -10,6 +10,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- TZ=America/Havana
|
- TZ=America/Havana
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
|
# Pasa el nombre del host al contenedor del notificador
|
||||||
|
- WATCHTOWER_NOTIFICATIONS_HOSTNAME=Servidor-Easypanel
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@ -1,252 +1,253 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
#watchtower_telegram_notifier.py
|
"""
|
||||||
"""
|
Watchtower Telegram Notifier - Notificaciones personalizadas en español
|
||||||
Watchtower Telegram Notifier - Notificaciones personalizadas en español
|
Monitorea los logs de Watchtower y envía notificaciones detalladas a Telegram
|
||||||
Monitorea los logs de Watchtower y envÃa notificaciones detalladas a Telegram
|
"""
|
||||||
"""
|
|
||||||
|
import docker
|
||||||
import docker
|
import requests
|
||||||
import requests
|
import time
|
||||||
import time
|
import re
|
||||||
import re
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
TELEGRAM_BOT_TOKEN = "7676713419:AAG-tfwzgrA9JaU5xNjvG5iBlFeZpz2ahiY"
|
TELEGRAM_BOT_TOKEN = "7676713419:AAG-tfwzgrA9JaU5xNjvG5iBlFeZpz2ahiY"
|
||||||
TELEGRAM_CHAT_ID = "7940222048"
|
TELEGRAM_CHAT_ID = "7940222048"
|
||||||
WATCHTOWER_CONTAINER_NAME = "watchtower"
|
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')
|
# Configurar logging
|
||||||
logger = logging.getLogger(__name__)
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
class WatchtowerTelegramNotifier:
|
|
||||||
def __init__(self):
|
class WatchtowerTelegramNotifier:
|
||||||
self.client = docker.from_env()
|
def __init__(self):
|
||||||
self.telegram_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
self.client = docker.from_env()
|
||||||
self.container_updates = {}
|
self.telegram_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
||||||
self.scan_in_progress = False
|
self.container_updates = {}
|
||||||
|
self.scan_in_progress = False
|
||||||
def send_telegram_message(self, message):
|
|
||||||
"""EnvÃa mensaje a Telegram"""
|
def send_telegram_message(self, message):
|
||||||
try:
|
"""Envía mensaje a Telegram"""
|
||||||
payload = {
|
try:
|
||||||
'chat_id': TELEGRAM_CHAT_ID,
|
payload = {
|
||||||
'text': message,
|
'chat_id': TELEGRAM_CHAT_ID,
|
||||||
'parse_mode': 'HTML'
|
'text': message,
|
||||||
}
|
'parse_mode': 'HTML'
|
||||||
response = requests.post(self.telegram_url, data=payload, timeout=10)
|
}
|
||||||
if response.status_code == 200:
|
response = requests.post(self.telegram_url, data=payload, timeout=10)
|
||||||
logger.info("✅ Mensaje enviado a Telegram exitosamente")
|
if response.status_code == 200:
|
||||||
return True
|
logger.info("✅ Mensaje enviado a Telegram exitosamente")
|
||||||
else:
|
return True
|
||||||
logger.error(f"⌠Error enviando mensaje: {response.status_code}")
|
else:
|
||||||
return False
|
logger.error(f"❌ Error enviando mensaje: {response.status_code}")
|
||||||
except Exception as e:
|
return False
|
||||||
logger.error(f"⌠Error conectando a Telegram: {e}")
|
except Exception as e:
|
||||||
return False
|
logger.error(f"❌ Error conectando a Telegram: {e}")
|
||||||
|
return False
|
||||||
def format_startup_message(self):
|
|
||||||
"""Mensaje de inicio del sistema"""
|
def format_startup_message(self):
|
||||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
"""Mensaje de inicio del sistema"""
|
||||||
message = f"""🔄 <b>WATCHTOWER INICIADO</b>
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
message = f"""🔄 <b>WATCHTOWER INICIADO</b>
|
||||||
ðŸ <b>Servidor:</b> {HOSTNAME}
|
|
||||||
📅 <b>Fecha:</b> {now}
|
🏠 <b>Servidor:</b> {HOSTNAME}
|
||||||
âš™ï¸ <b>Estado:</b> Monitoreo activo
|
📅 <b>Fecha:</b> {now}
|
||||||
🕠<b>Intervalo:</b> Cada 24 horas
|
⚙️ <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()
|
try:
|
||||||
for container in containers:
|
containers = self.client.containers.list()
|
||||||
if container.name != WATCHTOWER_CONTAINER_NAME:
|
for container in containers:
|
||||||
status_emoji = "🟢" if container.status == "running" else "🔴"
|
if container.name != WATCHTOWER_CONTAINER_NAME:
|
||||||
message += f"\n{status_emoji} {container.name}"
|
status_emoji = "🟢" if container.status == "running" else "🔴"
|
||||||
except Exception as e:
|
message += f"\n{status_emoji} {container.name}"
|
||||||
logger.error(f"Error obteniendo contenedores: {e}")
|
except Exception as e:
|
||||||
|
logger.error(f"Error obteniendo contenedores: {e}")
|
||||||
message += "\n\n✅ <b>Sistema listo para detectar actualizaciones</b>"
|
|
||||||
return message
|
message += "\n\n✅ <b>Sistema listo para detectar actualizaciones</b>"
|
||||||
|
return message
|
||||||
def format_scan_start_message(self):
|
|
||||||
"""Mensaje cuando inicia un escaneo"""
|
def format_scan_start_message(self):
|
||||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
"""Mensaje cuando inicia un escaneo"""
|
||||||
return f"""🔠<b>ESCANEO DE ACTUALIZACIONES INICIADO</b>
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
return f"""🔍 <b>ESCANEO DE ACTUALIZACIONES INICIADO</b>
|
||||||
ðŸ <b>Servidor:</b> {HOSTNAME}
|
|
||||||
📅 <b>Fecha:</b> {now}
|
🏠 <b>Servidor:</b> {HOSTNAME}
|
||||||
Ⳡ<b>Estado:</b> Verificando imágenes...
|
📅 <b>Fecha:</b> {now}
|
||||||
|
⏳ <b>Estado:</b> Verificando imágenes...
|
||||||
<i>Buscando actualizaciones disponibles...</i>"""
|
|
||||||
|
<i>Buscando actualizaciones disponibles...</i>"""
|
||||||
def format_update_report(self, updated_containers, checked_containers):
|
|
||||||
"""Formato del reporte final de actualizaciones"""
|
def format_update_report(self, updated_containers, checked_containers):
|
||||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
"""Formato del reporte final de actualizaciones"""
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
if updated_containers:
|
|
||||||
message = f"""🎉 <b>ACTUALIZACIONES COMPLETADAS</b>
|
if updated_containers:
|
||||||
|
message = f"""🎉 <b>ACTUALIZACIONES COMPLETADAS</b>
|
||||||
ðŸ <b>Servidor:</b> {HOSTNAME}
|
|
||||||
📅 <b>Fecha:</b> {now}
|
🏠 <b>Servidor:</b> {HOSTNAME}
|
||||||
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
|
📅 <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>"
|
for container_info in updated_containers:
|
||||||
message += f"\n 📋 Imagen: <code>{container_info['image']}</code>"
|
message += f"\n✅ <b>{container_info['name']}</b>"
|
||||||
if container_info.get('old_image'):
|
message += f"\n 📋 Imagen: <code>{container_info['image']}</code>"
|
||||||
message += f"\n 🔄 Desde: <code>{container_info['old_image']}</code>"
|
if container_info.get('old_image'):
|
||||||
|
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:
|
unchanged = [c for c in checked_containers if c not in [u['name'] for u in updated_containers]]
|
||||||
message += f"\n\n<b>â„¹ï¸ SIN CAMBIOS:</b>"
|
if unchanged:
|
||||||
for container in unchanged:
|
message += f"\n\n<b>ℹ️ SIN CAMBIOS:</b>"
|
||||||
message += f"\n🔘 {container}"
|
for container in unchanged:
|
||||||
|
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>
|
else:
|
||||||
|
message = f"""ℹ️ <b>VERIFICACIÓN COMPLETADA</b>
|
||||||
ðŸ <b>Servidor:</b> {HOSTNAME}
|
|
||||||
📅 <b>Fecha:</b> {now}
|
🏠 <b>Servidor:</b> {HOSTNAME}
|
||||||
📦 <b>Contenedores verificados:</b> {len(checked_containers)}
|
📅 <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"
|
for container in checked_containers:
|
||||||
|
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
|
|
||||||
|
return message
|
||||||
def parse_watchtower_logs(self, log_line):
|
|
||||||
"""Analiza lÃneas de log de Watchtower"""
|
def parse_watchtower_logs(self, log_line):
|
||||||
log_line = log_line.strip()
|
"""Analiza líneas de log de Watchtower"""
|
||||||
|
log_line = log_line.strip()
|
||||||
# Detectar inicio de escaneo
|
|
||||||
if "Checking all containers" in log_line and not self.scan_in_progress:
|
# Detectar inicio de escaneo
|
||||||
self.scan_in_progress = True
|
if "Checking all containers" in log_line and not self.scan_in_progress:
|
||||||
self.container_updates.clear()
|
self.scan_in_progress = True
|
||||||
self.send_telegram_message(self.format_scan_start_message())
|
self.container_updates.clear()
|
||||||
return
|
self.send_telegram_message(self.format_scan_start_message())
|
||||||
|
return
|
||||||
# Detectar actualizaciones
|
|
||||||
update_patterns = [
|
# Detectar actualizaciones
|
||||||
r'Found new.*image for (.+)',
|
update_patterns = [
|
||||||
r'Updating (.+?) with.*',
|
r'Found new.*image for (.+)',
|
||||||
r'Updated (.+?) \(.*\)'
|
r'Updating (.+?) with.*',
|
||||||
]
|
r'Updated (.+?) \(.*\)'
|
||||||
|
]
|
||||||
for pattern in update_patterns:
|
|
||||||
match = re.search(pattern, log_line, re.IGNORECASE)
|
for pattern in update_patterns:
|
||||||
if match:
|
match = re.search(pattern, log_line, re.IGNORECASE)
|
||||||
container_name = match.group(1)
|
if match:
|
||||||
if container_name not in self.container_updates:
|
container_name = match.group(1)
|
||||||
self.container_updates[container_name] = {
|
if container_name not in self.container_updates:
|
||||||
'name': container_name,
|
self.container_updates[container_name] = {
|
||||||
'image': 'Detectando...',
|
'name': container_name,
|
||||||
'updated': True
|
'image': 'Detectando...',
|
||||||
}
|
'updated': True
|
||||||
logger.info(f"📦 Actualización detectada: {container_name}")
|
}
|
||||||
break
|
logger.info(f"📦 Actualización detectada: {container_name}")
|
||||||
|
break
|
||||||
# Detectar fin de proceso
|
|
||||||
if any(phrase in log_line.lower() for phrase in ["session done", "watchtower will check again", "sleeping"]):
|
# Detectar fin de proceso
|
||||||
if self.scan_in_progress:
|
if any(phrase in log_line.lower() for phrase in ["session done", "watchtower will check again", "sleeping"]):
|
||||||
self.send_update_report()
|
if self.scan_in_progress:
|
||||||
self.scan_in_progress = False
|
self.send_update_report()
|
||||||
|
self.scan_in_progress = False
|
||||||
def send_update_report(self):
|
|
||||||
"""EnvÃa el reporte final de actualizaciones"""
|
def send_update_report(self):
|
||||||
try:
|
"""Envía el reporte final de actualizaciones"""
|
||||||
# Obtener lista actual de contenedores
|
try:
|
||||||
containers = self.client.containers.list(all=True)
|
# Obtener lista actual de contenedores
|
||||||
container_names = [c.name for c in containers if c.name != WATCHTOWER_CONTAINER_NAME]
|
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
|
|
||||||
updated_list = []
|
# Completar información de contenedores actualizados
|
||||||
for container_name, info in self.container_updates.items():
|
updated_list = []
|
||||||
try:
|
for container_name, info in self.container_updates.items():
|
||||||
container = self.client.containers.get(container_name)
|
try:
|
||||||
info['image'] = container.image.tags[0] if container.image.tags else "Sin tag"
|
container = self.client.containers.get(container_name)
|
||||||
except:
|
info['image'] = container.image.tags[0] if container.image.tags else "Sin tag"
|
||||||
info['image'] = "Imagen no encontrada"
|
except:
|
||||||
updated_list.append(info)
|
info['image'] = "Imagen no encontrada"
|
||||||
|
updated_list.append(info)
|
||||||
# Enviar reporte
|
|
||||||
report = self.format_update_report(updated_list, container_names)
|
# Enviar reporte
|
||||||
self.send_telegram_message(report)
|
report = self.format_update_report(updated_list, container_names)
|
||||||
|
self.send_telegram_message(report)
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error generando reporte: {e}")
|
except Exception as e:
|
||||||
error_msg = f"⌠<b>Error generando reporte de actualizaciones</b>\n\nðŸ <b>Servidor:</b> {HOSTNAME}\nâš ï¸ <b>Error:</b> {str(e)}"
|
logger.error(f"Error generando reporte: {e}")
|
||||||
self.send_telegram_message(error_msg)
|
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"""
|
def monitor_watchtower(self):
|
||||||
logger.info("🔠Iniciando monitoreo de Watchtower...")
|
"""Monitorea logs de Watchtower en tiempo real"""
|
||||||
|
logger.info("🔍 Iniciando monitoreo de Watchtower...")
|
||||||
try:
|
|
||||||
container = self.client.containers.get(WATCHTOWER_CONTAINER_NAME)
|
try:
|
||||||
logger.info(f"✅ Contenedor Watchtower encontrado: {container.id[:12]}")
|
container = self.client.containers.get(WATCHTOWER_CONTAINER_NAME)
|
||||||
|
logger.info(f"✅ Contenedor Watchtower encontrado: {container.id[:12]}")
|
||||||
# Enviar mensaje de inicio
|
|
||||||
self.send_telegram_message(self.format_startup_message())
|
# Enviar mensaje de inicio
|
||||||
|
self.send_telegram_message(self.format_startup_message())
|
||||||
# Monitorear logs en tiempo real
|
|
||||||
for log in container.logs(stream=True, follow=True, tail=10):
|
# Monitorear logs en tiempo real
|
||||||
try:
|
for log in container.logs(stream=True, follow=True, tail=10):
|
||||||
log_line = log.decode('utf-8').strip()
|
try:
|
||||||
if log_line:
|
log_line = log.decode('utf-8').strip()
|
||||||
logger.debug(f"Log: {log_line}")
|
if log_line:
|
||||||
self.parse_watchtower_logs(log_line)
|
logger.debug(f"Log: {log_line}")
|
||||||
except Exception as e:
|
self.parse_watchtower_logs(log_line)
|
||||||
logger.error(f"Error procesando log: {e}")
|
except Exception as e:
|
||||||
continue
|
logger.error(f"Error procesando log: {e}")
|
||||||
|
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}"
|
except docker.errors.NotFound:
|
||||||
self.send_telegram_message(error_msg)
|
error_msg = f"❌ <b>ERROR: Contenedor Watchtower no encontrado</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Nombre esperado:</b> {WATCHTOWER_CONTAINER_NAME}"
|
||||||
logger.error("⌠Contenedor Watchtower no encontrado")
|
self.send_telegram_message(error_msg)
|
||||||
except Exception as e:
|
logger.error("❌ Contenedor Watchtower no encontrado")
|
||||||
error_msg = f"⌠<b>ERROR EN MONITOREO</b>\n\nðŸ <b>Servidor:</b> {HOSTNAME}\nâš ï¸ <b>Error:</b> {str(e)}"
|
except Exception as e:
|
||||||
self.send_telegram_message(error_msg)
|
error_msg = f"❌ <b>ERROR EN MONITOREO</b>\n\n🏠 <b>Servidor:</b> {HOSTNAME}\n⚠️ <b>Error:</b> {str(e)}"
|
||||||
logger.error(f"⌠Error en monitoreo: {e}")
|
self.send_telegram_message(error_msg)
|
||||||
|
logger.error(f"❌ Error en monitoreo: {e}")
|
||||||
def main():
|
|
||||||
logger.info("🚀 Iniciando Watchtower Telegram Notifier...")
|
def main():
|
||||||
|
logger.info("🚀 Iniciando Watchtower Telegram Notifier...")
|
||||||
notifier = WatchtowerTelegramNotifier()
|
|
||||||
|
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")
|
if notifier.send_telegram_message(test_message):
|
||||||
else:
|
logger.info("✅ Conexión a Telegram verificada")
|
||||||
logger.error("⌠Error de conexión a Telegram")
|
else:
|
||||||
return
|
logger.error("❌ Error de conexión a Telegram")
|
||||||
|
return
|
||||||
# Iniciar monitoreo
|
|
||||||
try:
|
# Iniciar monitoreo
|
||||||
notifier.monitor_watchtower()
|
try:
|
||||||
except KeyboardInterrupt:
|
notifier.monitor_watchtower()
|
||||||
logger.info("🛑 Monitoreo interrumpido por el usuario")
|
except KeyboardInterrupt:
|
||||||
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")
|
||||||
notifier.send_telegram_message(farewell_msg)
|
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>"
|
||||||
except Exception as e:
|
notifier.send_telegram_message(farewell_msg)
|
||||||
logger.error(f"⌠Error fatal: {e}")
|
except Exception as 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}")
|
||||||
notifier.send_telegram_message(error_msg)
|
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__":
|
|
||||||
main()
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user