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())