Node.js中使用TDLib导入Telegram联系人失败并遇429错误求助
解决TDLib连接错误与速率限制问题
看起来你遇到了两个核心问题:IPv6路由失败导致的连接错误,以及Telegram的请求速率限制中断了操作。下面一步步帮你解决:
1. 修复No route to host连接错误
这个错误是因为TDLib默认优先尝试IPv6连接,但你的网络环境可能不支持IPv6,或者目标IPv6节点不可达。你可以强制TDLib使用IPv4,修改客户端初始化配置:
const telegramConnect = async () => { const { Client } = require('tdl'); const { TDLib } = require('tdl-tdlib-ffi'); const number = '+9196xxxxxx43'; const telegramClient = new Client(new TDLib(), { number, apiId: 86xxx5, apiHash: '27xxxxxxxxxxxxxxxxxc7b1', use_ipv6: false // 强制使用IPv4连接,避免IPv6路由问题 }); telegramClient.on('Telegram Connection Error ', console.error); // 建议新增全局错误监听,捕获更多异常 telegramClient.on('error', err => console.error('TDLib全局错误:', err)); await telegramClient.connectAndLogin(); return telegramClient; }
2. 处理429速率限制错误
Telegram对importContacts、发送消息这类操作有严格的频率限制,触发429错误时必须按提示等待后重试。你可以封装带重试逻辑的工具函数,或者拆分批量操作:
方案一:封装带重试的invoke函数
写一个通用函数处理429错误的自动重试:
const invokeWithRetry = async (client, method, retries = 3) => { try { return await client.invoke(method); } catch (error) { // 匹配429错误中的重试等待时间 if (error.code === 429 && retries > 0) { const retryAfterMatch = error.message.match(/retry after (\d+)/); if (retryAfterMatch) { const retryAfter = parseInt(retryAfterMatch[1], 10); console.log(`触发速率限制,将在${retryAfter}秒后重试...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); return invokeWithRetry(client, method, retries - 1); } } throw error; } }; // 替换原有的importContacts调用 const importContact = await invokeWithRetry(client, { _: 'importContacts', contacts: contacts });
方案二:拆分联系人批量导入(适合大量联系人场景)
如果需要导入的联系人数量较多,建议分成小批量导入,每批之间添加间隔:
const batchImportContacts = async (client, contacts, batchSize = 5, delayMs = 10000) => { const results = []; for (let i = 0; i < contacts.length; i += batchSize) { const batch = contacts.slice(i, i + batchSize); try { const result = await client.invoke({ _: 'importContacts', contacts: batch }); results.push(result); console.log(`成功导入第${Math.floor(i/batchSize)+1}批联系人`); await new Promise(resolve => setTimeout(resolve, delayMs)); } catch (error) { if (error.code === 429) { const retryAfter = parseInt(error.message.match(/retry after (\d+)/)[1], 10); console.log(`当前批次触发限制,等待${retryAfter}秒后重试...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); i -= batchSize; // 回退索引,重新处理当前批次 } else { throw error; } } } return results; }; // 使用方式 const importResult = await batchImportContacts(client, contacts);
3. 发送消息时的速率控制
导入联系人后发送消息同样需要注意限流,你可以复用类似的重试逻辑,或者添加固定间隔:
const sendMessageWithRetry = async (client, chatId, messageText, retries = 3) => { try { return await client.invoke({ _: 'sendMessage', chat_id: chatId, input_message_content: { _: 'inputMessageText', text: { _: 'formattedText', text: messageText } } }); } catch (error) { if (error.code === 429 && retries > 0) { const retryAfter = parseInt(error.message.match(/retry after (\d+)/)[1], 10); console.log(`发送消息触发限制,${retryAfter}秒后重试...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); return sendMessageWithRetry(client, chatId, messageText, retries - 1); } throw error; } }; // 遍历导入的用户发送消息 for (const user of importResult.users) { await sendMessageWithRetry(client, user.id, "你的消息内容"); await new Promise(resolve => setTimeout(resolve, 5000)); // 每条消息间隔5秒,降低触发限制概率 }
额外提示
- 确保你的API ID和Hash是在Telegram开发者平台正确注册的,新账号的操作限制会更严格,建议先用少量测试数据验证。
- 避免短时间内进行高频操作,Telegram的限制会根据账号活跃度动态调整。
内容的提问来源于stack exchange,提问作者Jegan
相关产品推荐
相关产品推荐

