如何借助node-telegram-bot-api用JS/TS获取Telegram公开群组聊天历史?
用JavaScript/TypeScript获取Telegram公开群组全部消息
首先要明确:你提到的messages.getHistory是Telegram MTProto API的方法,但你当前使用的node-telegram-bot-api封装的是官方Bot API,二者不属于同一套接口。下面分两种方案说明实现方式:
方案一:用node-telegram-bot-api(Bot API)实现
Bot API里对应的拉取聊天记录方法是getChatHistory,由于每次请求最多返回100条消息,所以需要循环分页拉取直到没有新消息返回。
步骤:
- 确保你的Bot已加入目标公开群组,获取群组的
chat_id(可通过调用getUpdates接口获取,超级群组的chat_id通常为-100xxxxxxxxx格式)。 - 循环调用
getChatHistory,每次传入上一页最后一条消息的message_id作为offset_id,直到返回的消息数组为空。
JavaScript代码示例:
const TelegramBot = require('node-telegram-bot-api'); const token = '你的Bot Token'; const chatId = '-1001234567890'; // 替换为目标群组的chat_id const bot = new TelegramBot(token, { polling: false }); async function fetchAllMessages() { let allMessages = []; let offsetId = 0; const limit = 100; // Bot API单次请求的最大返回条数 while (true) { try { const messages = await bot.getChatHistory(chatId, offsetId, 0, limit); if (messages.length === 0) break; allMessages = [...allMessages, ...messages]; offsetId = messages[messages.length - 1].message_id; // 避免触发Telegram频率限制,每次请求后延迟1秒 await new Promise(resolve => setTimeout(resolve, 1000)); } catch (error) { console.error('拉取消息失败:', error); break; } } console.log('全部消息拉取完成,总条数:', allMessages.length); // 后续可将消息保存到文件/数据库或做其他处理 } fetchAllMessages();
TypeScript代码示例:
import TelegramBot from 'node-telegram-bot-api'; const token = '你的Bot Token'; const chatId = '-1001234567890'; // 替换为目标群组的chat_id const bot = new TelegramBot(token, { polling: false }); async function fetchAllMessages(): Promise<void> { let allMessages: TelegramBot.Message[] = []; let offsetId = 0; const limit = 100; while (true) { try { const messages = await bot.getChatHistory(chatId, offsetId, 0, limit); if (messages.length === 0) break; allMessages = [...allMessages, ...messages]; offsetId = messages[messages.length - 1].message_id; await new Promise(resolve => setTimeout(resolve, 1000)); } catch (error) { console.error('拉取消息失败:', error); break; } } console.log('全部消息拉取完成,总条数:', allMessages.length); } fetchAllMessages();
方案二:使用MTProto API调用messages.getHistory
如果你确实需要使用MTProto的messages.getHistory方法,node-telegram-bot-api无法直接支持,需使用专门的MTProto库(如telegram-mtproto)。
步骤:
- 从Telegram官方平台注册应用,获取
api_id和api_hash。 - 安装依赖:
npm install telegram-mtproto。 - 初始化客户端并登录个人账号(注意:此方案需使用个人账号而非Bot账号),循环调用
messages.getHistory分页拉取消息。
JavaScript代码示例:
const { MTProto } = require('telegram-mtproto'); const api = { id: 123456, // 替换为你的api_id hash: 'abcdef1234567890abcdef1234567890' // 替换为你的api_hash }; const client = MTProto({ api, test: false // 生产环境设为false }); async function login() { // 完成登录流程:发送验证码、验证登录 const { phone_code_hash } = await client('auth.sendCode', { phone_number: '+1234567890', settings: { _: 'codeSettings' } }); // 假设已获取到验证码,替换为实际验证码 await client('auth.signIn', { phone_number: '+1234567890', phone_code_hash, phone_code: '123456' }); } async function fetchAllMTProtoMessages() { await login(); let allMessages = []; let offset = 0; const limit = 100; // 替换为目标群组的channel_id和access_hash,可通过channels.getChannels接口获取 const peer = { _: 'inputPeerChannel', channel_id: 123456, access_hash: 78901234567890 }; while (true) { try { const { messages } = await client('messages.getHistory', { peer, offset_id: offset, limit }); if (!messages || messages.length === 0) break; allMessages = [...allMessages, ...messages]; offset = messages[messages.length - 1].id; await new Promise(resolve => setTimeout(resolve, 1000)); } catch (error) { console.error('拉取消息失败:', error); break; } } console.log('全部消息拉取完成,总条数:', allMessages.length); } fetchAllMTProtoMessages();
注意事项:
- 频率限制:Telegram对API请求有严格的频率限制,必须添加延迟,否则可能导致账号/Bot被封禁。
- 权限问题:Bot需被添加到目标群组且拥有消息读取权限;MTProto方案需确保个人账号能正常访问目标公开群组。
- 格式转换:超级群组在Bot API中的
chat_id为-100xxxxxxxxx,MTProto中需转换为包含channel_id和access_hash的inputPeerChannel格式。
内容的提问来源于stack exchange,提问作者Тыква
相关产品推荐
相关产品推荐

