Files
traduccion_bots/botdiscord/server_sync.py

205 lines
6.6 KiB
Python

import discord
from discord.ext import commands
import asyncio
import sys
import os
# Agregar el path del proyecto para importar configuración
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from botdiscord.config import load_config, get_discord_token
from botdiscord.database import sync_discord_servers, sync_discord_channels, delete_server_channels
# Variables globales para el bot
_bot_instance = None
_client = None
async def get_discord_client():
"""Obtiene o crea una instancia del cliente de Discord"""
global _client
if _client is None:
intents = discord.Intents.default()
intents.guilds = True # Necesario para obtener servidores
intents.message_content = False # No necesitamos leer mensajes
_client = discord.Client(intents=intents)
# Evento de conexión
@_client.event
async def on_ready():
print(f"[Discord Sync] Conectado como {_client.user}")
return _client
async def sync_discord_servers_from_api():
"""
Sincroniza los servidores y canales desde Discord API
Returns True si fue exitoso, False si hubo error
"""
global _client
try:
print("[Discord Sync] Iniciando sincronización...")
# Cargar configuración
load_config()
token = get_discord_token()
print(f"[Discord Sync] Token encontrado: {bool(token)}")
print(f"[Discord Sync] Token length: {len(token) if token else 0}")
if not token:
print("[Discord Sync] Error: No se encontró el token de Discord")
print("[Discord Sync] Variables de entorno disponibles:")
for key, value in os.environ.items():
if 'DISCORD' in key or 'TOKEN' in key:
print(f" {key}: {'***' if 'TOKEN' in key else value}")
return False
# Obtener cliente de Discord
client = await get_discord_client()
# Conectar si no está conectado
if not client.is_ready():
try:
print("[Discord Sync] Conectando a Discord...")
await client.login(token)
asyncio.create_task(client.connect())
# Esperar hasta que el bot esté listo
await client.wait_until_ready()
except Exception as e:
print(f"[Discord Sync] Error conectando a Discord: {e}")
return False
# Obtener servidores donde está el bot
guilds = client.guilds
servers_data = []
for guild in guilds:
servers_data.append({
'id': guild.id,
'name': guild.name
})
# Sincronizar servidores en la base de datos
sync_discord_servers(servers_data)
print(f"[Discord Sync] Sincronizados {len(servers_data)} servidores")
# Sincronizar canales para cada servidor
for guild in guilds:
try:
# Obtener canales de texto del servidor
text_channels = [ch for ch in guild.text_channels]
channels_data = []
for channel in text_channels:
channels_data.append({
'id': channel.id,
'name': channel.name
})
# Sincronizar canales del servidor
sync_discord_channels(guild.id, channels_data)
print(f"[Discord Sync] Sincronizados {len(channels_data)} canales del servidor {guild.name}")
except Exception as e:
print(f"[Discord Sync] Error sincronizando canales del servidor {guild.name}: {e}")
# Eliminar canales de este servidor si hay error
delete_server_channels(guild.id)
# Desconectar cliente para liberar recursos
if client.is_ready():
await client.close()
_client = None
return True
except Exception as e:
print(f"[Discord Sync] Error general: {e}")
# Limpiar cliente en caso de error
if _client and _client.is_ready():
try:
await _client.close()
except:
pass
_client = None
return False
async def get_server_channels(server_id: int):
"""
Obtiene los canales de un servidor específico desde Discord API
"""
try:
client = await get_discord_client()
token = get_discord_token()
if not token:
return []
# Conectar si es necesario
if not client.is_ready():
await client.login(token)
asyncio.create_task(client.connect())
await client.wait_until_ready()
# Buscar el servidor
guild = client.get_guild(server_id)
if not guild:
print(f"[Discord Sync] No se encontró el servidor {server_id}")
return []
# Obtener canales de texto
text_channels = [ch for ch in guild.text_channels]
channels_data = []
for channel in text_channels:
channels_data.append({
'id': channel.id,
'name': channel.name
})
# Cerrar cliente
if client.is_ready():
await client.close()
_client = None
return channels_data
except Exception as e:
print(f"[Discord Sync] Error obteniendo canales del servidor {server_id}: {e}")
return []
# Función de prueba para verificar la conexión
async def test_discord_connection():
"""Prueba la conexión con Discord API"""
try:
client = await get_discord_client()
token = get_discord_token()
if not token:
return False, "No hay token de Discord"
await client.login(token)
asyncio.create_task(client.connect())
await client.wait_until_ready()
# Verificar si podemos obtener guilds
guilds = client.guilds
await client.close()
_client = None
return True, f"Conexión exitosa. Bot en {len(guilds)} servidores"
except Exception as e:
return False, f"Error de conexión: {e}"
if __name__ == "__main__":
# Prueba de sincronización
async def test_sync():
print("Iniciando prueba de sincronización...")
result = await sync_discord_servers_from_api()
print(f"Resultado: {'Exitoso' if result else 'Fallido'}")
asyncio.run(test_sync())