无需手机登录,用Telegram API/Bot获取频道最新20条消息(TS/Node.js)
方案1:使用Telegram Bot API(优先实现)
前置要求
- 目标频道需添加Bot为成员并授予读取消息权限(公开频道无需添加,直接可访问)
- 已通过@BotFather获取Bot的
TOKEN
1. 安装依赖
选用TS友好的telegraf框架:
npm install telegraf npm install -D @types/telegraf typescript ts-node
2. 核心TS代码
import { Telegraf } from 'telegraf'; import express from 'express'; const bot = new Telegraf('YOUR_BOT_TOKEN'); const app = express(); // 获取频道最新20条消息的核心函数 async function fetchLatestChannelMessages(channelIdentifier: string, limit = 20) { try { // 验证Bot权限 const chat = await bot.telegram.getChat(channelIdentifier); if (!chat.can_read_history) { throw new Error('Bot无读取该频道消息的权限'); } // 拉取最新消息,offset设为0从最新条目开始 const rawMessages = await bot.telegram.getChatHistory(channelIdentifier, 0, limit); // 格式化返回数据(按需提取字段) return rawMessages.map(msg => ({ messageId: msg.message_id, content: msg.text || msg.caption || '无文本内容', sendTime: new Date(msg.date * 1000), sender: msg.from ? `${msg.from.first_name} ${msg.from.last_name || ''}` : '系统/匿名', mediaId: msg.photo ? msg.photo.at(-1)?.file_id : null })); } catch (err) { console.error('拉取消息失败:', err); throw err; } } // 无状态API接口示例 app.get('/api/latest-channel-messages', async (req, res) => { const channel = req.query.channel as string; if (!channel) { return res.status(400).json({ error: '请传入频道标识(@用户名或chat_id)' }); } try { const messages = await fetchLatestChannelMessages(channel); res.json(messages); } catch (err) { res.status(500).json({ error: (err as Error).message }); } }); app.listen(3000, () => console.log('API服务已启动在端口3000'));
关键注意点
- 公开频道用
@channelusername作为标识,私有频道需使用频道的chat_id(可通过Bot给频道发消息后,从getUpdates接口获取) - 需遵守Telegram Bot API的调用频率限制,避免触发限流
- 无状态环境下,Bot实例可单例复用,无需每次请求重新初始化
方案2:使用Telegram MTProto API(API ID/Hash)
当Bot无法访问目标频道时(如频道拒绝Bot加入),可采用此方案,无需维持用户会话,使用API ID/Hash即可实现。
前置要求
- 已从my.telegram.org注册获取API ID和API Hash
- 若使用Bot账号,需先通过@BotFather获取Bot Token
1. 安装依赖
选用支持TS的MTProto库gramjs:
npm install gramjs npm install -D typescript ts-node
2. 核心TS代码
import { TelegramClient } from 'gramjs'; import { StringSession } from 'gramjs/sessions'; import express from 'express'; const API_ID = 123456; // 替换为你的API ID const API_HASH = 'your_api_hash_here'; const BOT_TOKEN = 'your_bot_token_here'; const app = express(); // 创建MTProto客户端并登录Bot async function initClient() { const session = new StringSession(''); const client = new TelegramClient(session, API_ID, API_HASH, { connectionRetries: 3, }); await client.start({ botAuthToken: BOT_TOKEN }); return client; } // 获取频道最新20条消息 async function fetchLatestChannelMessages(channelIdentifier: string, limit = 20) { let client: TelegramClient | undefined; try { client = await initClient(); const channel = await client.getEntity(channelIdentifier); // 拉取最新消息,reverse=false表示从最新条目开始 const rawMessages = await client.getMessages(channel, { limit }); return rawMessages.map(msg => ({ messageId: msg.id, content: msg.text || msg.caption || '无文本内容', sendTime: msg.date, sender: msg.senderId ? await client.getEntity(msg.senderId).then(e => e.username || e.firstName) : '匿名', mediaType: msg.media ? msg.media.className : null })); } catch (err) { console.error('拉取消息失败:', err); throw err; } finally { if (client) await client.disconnect(); } } // 无状态API接口示例 app.get('/api/latest-channel-messages', async (req, res) => { const channel = req.query.channel as string; if (!channel) { return res.status(400).json({ error: '请传入频道标识(@用户名或chat_id)' }); } try { const messages = await fetchLatestChannelMessages(channel); res.json(messages); } catch (err) { res.status(500).json({ error: (err as Error).message }); } }); app.listen(3000, () => console.log('API服务已启动在端口3000'));
关键注意点
- MTProto API的调用频率限制比BotAPI更严格,需控制请求频率
- 无状态环境下,可将登录后的会话字符串缓存(如存入Redis),避免每次请求重新登录
- 使用普通用户账号的API ID/Hash时,需注意Telegram的风控机制,避免频繁登录触发账号限制
内容的提问来源于stack exchange,提问作者FelixM.
相关产品推荐
相关产品推荐

