From e393d9bd9842d66415617907c4735343521ce099 Mon Sep 17 00:00:00 2001 From: BarryY Date: Fri, 16 May 2025 12:42:21 +0800 Subject: [PATCH] fix: Fix discord bot login timeout issues --- src/tools/login.ts | 115 +++++++-------------------------------------- 1 file changed, 16 insertions(+), 99 deletions(-) diff --git a/src/tools/login.ts b/src/tools/login.ts index 8e5674d..738dd1e 100644 --- a/src/tools/login.ts +++ b/src/tools/login.ts @@ -51,109 +51,26 @@ async function waitForReady(client: Client, token: string, timeoutMs = 30000): P export const loginHandler: ToolHandler = async (args, context) => { DiscordLoginSchema.parse(args); - try { - // Check if token is provided in the request - const token = args.token; - let { client } = context; - - // Log initial client state - info(`Login handler called with client state: ${JSON.stringify({ - isReady: client.isReady(), - hasToken: !!client.token, - hasArgsToken: !!token, - user: client.user ? { - id: client.user.id, - tag: client.user.tag, - } : null - })}`); - - // If token is provided and client is already logged in, logout first - if (token && client.isReady()) { - const currentBotTag = client.user?.tag || 'Unknown'; - info(`Logging out current client (${currentBotTag}) to switch to new token`); - - // Destroy the client connection to logout - await client.destroy(); - info('Client destroyed successfully'); - - // Create a new client instead of reusing the old one - info('Creating new client instance for new token'); - const newClient = new Client({ - intents: [ - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildMessages, - GatewayIntentBits.MessageContent, - GatewayIntentBits.GuildMessageReactions - ] - }); - - // Replace the old client in the context - Object.assign(context, { client: newClient }); - client = newClient; - - // Set the token on the new client - client.token = token; - info(`Token set on new client: ${!!client.token}`); - - // Login with the new token - info('Attempting login with new token on new client'); - try { - // Replace direct login with waitForReady - info('Waiting for client ready event'); - await waitForReady(client, token); - info(`Login successful and client is ready, new client user: ${client.user?.tag}`); + // Check if client is already logged in + if (context.client.isReady()) { + return { + content: [{ type: "text", text: `Already logged in as: ${context.client.user?.tag}` }] + }; + } + // loginHandler doesn't directly handle token, it needs to be set before invocation + if (!context.client.token) { + return { + content: [{ type: "text", text: "Discord token not configured. Cannot log in. Please check the following:\n1. Make sure the token is correctly set in your config or environment variables.\n\n2. Ensure all required privileged intents (Message Content, Server Members, Presence) are enabled in the Discord Developer Portal for your bot application." }], + isError: true + }; + } + + await context.client.login(context.client.token); return { - content: [{ type: "text", text: `Successfully switched from ${currentBotTag} to ${client.user?.tag}` }] + content: [{ type: "text", text: `Successfully logged in to Discord: ${context.client.user?.tag}` }] }; - } catch (innerError) { - error(`Failed to login after destroy: ${innerError instanceof Error ? innerError.message : String(innerError)}`); - return handleDiscordError(innerError); - } - } - - // Check if client is already logged in (and no new token provided) - if (client.isReady()) { - info(`Client already logged in as: ${client.user?.tag}`); - return { - content: [{ type: "text", text: `Already logged in as: ${client.user?.tag}` }] - }; - } - - // If token is provided in the request, use it - if (token) { - info('Setting token from request'); - client.token = token; - info(`Token set to request value: ${!!client.token}`); - } else { - info('No token in request, checking for existing token'); - } - - // Token needs to be set before login - if (!client.token) { - error('No token available for login'); - return { - content: [{ type: "text", text: "Discord token not configured. Cannot log in. Please provide a token in your request or configure it using environment variables." }], - isError: true - }; - } - - info('Attempting login with token'); - try { - // Replace direct login with waitForReady - info('Waiting for client ready event'); - await waitForReady(client, token || client.token); - info(`Login successful and client is ready, client user: ${client.user?.tag}`); - - info(`Login fully completed, ready state: ${client.isReady()}`); - return { - content: [{ type: "text", text: `Successfully logged in to Discord: ${client.user?.tag}` }] - }; - } catch (loginError) { - error(`Login attempt failed: ${loginError instanceof Error ? loginError.message : String(loginError)}`); - return handleDiscordError(loginError); - } } catch (err) { error(`Error in login handler: ${err instanceof Error ? err.message : String(err)}`); return handleDiscordError(err);