使用Telegram Node.js API下载图片时触发400 CONNECTION_NOT_INITED错误的问题求助
Telegram Node.js API下载图片时触发400 CONNECTION_NOT_INITED错误的问题求助
看起来你遇到的这个400 CONNECTION_NOT_INITED错误,核心问题出在**重复调用client.connect()**以及连接状态的管理上。我来帮你一步步排查和解决:
错误原因分析
这个错误的意思是:当调用底层的upload.GetFile方法(也就是你用的downloadFile)时,MTProto连接还没完成初始化。而你代码里的关键问题在于——你在每次下载图片的函数里都调用了await client.connect(),但你的client其实已经通过messages.GetHistory证明是能正常工作的(说明之前已经完成了连接和登录),重复调用connect()会打乱客户端的连接状态,导致执行下载请求时,连接处于未初始化的异常状态。
具体修复步骤
1. 把客户端连接/登录逻辑移到初始化阶段,只执行一次
你应该在应用启动的时候就完成客户端的连接和登录,而不是每次下载都重复执行。这样能保证客户端始终处于稳定的连接状态:
// 假设这是你的客户端初始化代码(放在应用入口,只执行一次) const { Telegram, Api } = require("telegram"); const { StringSession } = require("telegram/sessions"); const fs = require("fs"); const apiId = 123456; // 替换成你的API ID const apiHash = "your_api_hash_here"; // 替换成你的API Hash const session = new StringSession(""); // 可改用文件会话持久化登录状态 // 初始化全局复用的客户端实例 const client = new Telegram.Client(session, apiId, apiHash, { connectionRetries: 5, useWSS: true, // 推荐用WebSocket连接,稳定性更强 }); // 应用启动时执行的初始化函数 async function initTelegramClient() { try { await client.start({ phoneNumber: async () => "你的手机号", // 也可以用prompt动态获取 password: async () => "你的两步验证密码(如果有)", phoneCode: async () => "收到的验证码", onError: (err) => console.error("登录出错:", err), }); console.log("客户端已成功连接并登录,会话信息:", client.session.save()); } catch (err) { console.error("客户端初始化失败:", err); process.exit(1); } } // 先完成客户端初始化,再处理业务逻辑 (async () => { await initTelegramClient(); // 这里再调用你的getHistory和downloadPhoto逻辑 // 示例: // const req = new Api.messages.GetHistory({...}); // 你的历史消息请求参数 // const history = await client.invoke(req); // 遍历历史消息中的图片,调用downloadPhoto })();
2. 修改downloadPhoto函数,移除重复的connect()调用
现在客户端已经在初始化阶段完成了连接,下载函数里不需要再调用connect(),直接复用已连接的客户端即可:
const downloadPhoto = async (photo, client, name) => { const file = new Api.InputPhotoFileLocation({ id: photo.id, accessHash: photo.accessHash, fileReference: photo.fileReference, thumbSize: "y", // 这个尺寸是对的,对应最大分辨率的缩略图 }); try { // 直接使用已连接的客户端下载 const buffer = await client.downloadFile(file, { dcId: photo.dcId, // 这个参数是对的,确保连接到图片所在的数据中心 }); const savePath = name || "output.jpg"; fs.writeFileSync(savePath, buffer); console.log(`图片已成功保存到:${savePath}`); } catch (error) { console.error("下载图片出错:", error, "文件位置信息:", file); } };
额外注意事项
- 不要在多个地方重复创建
Telegram.Client实例,要全局复用同一个实例,避免连接冲突 - 如果你的应用长时间运行,可能会遇到连接断开的情况,这时候可以在下载前检查客户端状态:
if (!client.connected) { await client.connect(); // 仅在未连接时重新连接 } - 确保你使用的
telegram库是最新版本,可执行npm update telegram升级,旧版本可能存在一些连接相关的BUG
按照这个思路修改后,应该就能解决这个CONNECTION_NOT_INITED错误了。如果还有问题,可以检查一下你的API ID/Hash是否正确,以及会话是否有效~




