使用telegram包授权时PHONE_CODE_EXPIRED错误的解决求助
解决Telegram客户端授权时PHONE_CODE_EXPIRED错误(Bot输入验证码场景)
问题根源
你的代码中使用bot.onText注册的是全局永久监听器,每次调用author函数都会新增一个监听器。这会导致两个核心问题:
- 多个监听器同时存在时,输入的验证码可能被错误的监听器捕获,或者触发时机延迟,超过Telegram验证码120秒的有效期,最终抛出
PHONE_CODE_EXPIRED。 - 全局监听器不会自动清理,后续调用
author时会出现逻辑混乱,干扰正常的验证码获取流程。
而终端输入的方式(input.text)是同步阻塞的,能确保在有效期内获取到验证码,所以不会触发超时错误。
修复方案:使用一次性对话监听器
为每个输入请求创建仅响应当前对话的一次性监听器,确保只捕获当前用户的输入,并且在获取到内容后自动清理监听器,避免干扰后续流程。
修改后的完整代码
const author = async () => { console.log("Loading interactive example..."); const client = new TelegramClient(stringSession, parseInt(API_ID), API_HASH, { connectionRetries: 5, }); // 封装获取当前对话输入的工具函数 const getChatInput = async (prompt, regex) => { await bot.sendMessage(chatId, prompt); return new Promise((resolve) => { // 创建监听器,仅处理当前对话的消息 const listener = (msg) => { if (msg.chat.id !== chatId) return; if (regex.test(msg.text)) { resolve(msg.text); // 移除监听器,避免重复触发 bot.removeListener('text', listener); } else { bot.sendMessage(chatId, '输入格式不正确,请重新输入。'); } }; bot.on('text', listener); }); }; await client.start({ phoneNumber: async () => await getChatInput('Please enter phoneNumber.', /^\+[0-9]+$/), password: async () => await getChatInput('Please Enter Password ', /^[a-zA-Z0-9]+$/), phoneCode: async () => await getChatInput('Please Enter Phone Code ', /^[0-9]+$/), onError: (err) => console.log(err), }); console.log("You should now be connected."); const sessionString = client.session.save(); console.log(sessionString); await bot.sendMessage(chatId, `Here is your session string: ${sessionString}`); };
关键修改点
- 封装
getChatInput工具函数,统一处理对话输入逻辑:- 使用
bot.on创建监听器,并在匹配成功后手动移除,确保只响应一次当前对话的输入。 - 增加
chatId判断,避免其他用户的输入干扰当前授权流程。 - 对格式错误的输入给出提示,引导用户重新输入。
- 使用
- 替换原有的全局
bot.onText逻辑,改用工具函数获取输入,确保每个输入请求都是独立且一次性的。
验证效果
修改后,当你通过Bot输入验证码时,监听器会立即捕获当前对话的输入,不会出现延迟或错误捕获的情况,能在验证码有效期内完成授权,成功生成会话字符串。
内容的提问来源于stack exchange,提问作者Vishal Kumar
相关产品推荐
相关产品推荐

