如何用Telegraf JS检测Telegram用户已读消息事件?
我正在使用Telegraf JS开发Telegram Bot,该Bot会定期向用户发送消息。我希望能检测到用户何时已读Bot发送的消息(在Telegram应用中,消息右下角会出现小对勾v)。请问是否有方法让Bot检测这个事件?
我已查阅Telegraf JS文档但未找到相关内容。我使用TypeScript,查看了接受过滤器作为第一个参数、回调函数作为第二个参数的bot.on函数,例如捕获用户消息的示例:
telegraf.on('text', (ctx) => console.log('Got a message !'));
我在telegram-types.d.ts中找到了可能的过滤器:
export type UpdateType = 'callback_query' | 'channel_post' | 'chosen_inline_result' | 'edited_channel_post' | 'edited_message' | 'inline_query' | 'message' | 'pre_checkout_query' | 'shipping_query' | 'poll' | 'poll_answer' export type MessageSubTypes = 'voice' | 'video_note' | ...
也许存在一个与我的需求对应的过滤器,但我找不到解释所有类型含义的文档。
首先明确:Telegram Bot API本身并未提供用户已读消息的实时推送事件,所以你无法通过bot.on监听某个特定的Update类型来直接获取用户已读通知。你看到的UpdateType列表里没有相关类型,正是因为Telegram没有开放这个事件的推送。
不过有两种替代方案可以实现近似需求:
1. 定期轮询用户已读的最后消息ID
在私聊场景下,你可以通过Telegraf的ctx.telegram.getChat方法获取用户的聊天信息,其中last_read_message_id字段表示用户已读的最后一条消息的ID。你可以定期对比这个ID和你发送给用户的消息ID,判断消息是否已被读取。
示例代码:
// 发送消息后保存消息ID const sentMessageId = await ctx.telegram.sendMessage(ctx.chat.id, '定期推送的消息'); // 每30秒检查一次已读状态 const checkReadStatus = setInterval(async () => { const chat = await ctx.telegram.getChat(ctx.chat.id); if (chat.last_read_message_id >= sentMessageId) { console.log('用户已读消息!'); clearInterval(checkReadStatus); // 已读则停止轮询 } }, 30000);
注意:这种方法是轮询方式,并非实时通知,且仅适用于私聊场景,群组/频道无法通过该方式获取单个用户的已读状态。
2. 通过交互事件间接判断已读
如果你的推送消息包含交互式按钮(比如Inline Keyboard),当用户点击按钮触发callback_query事件时,你可以间接判断用户已经看到并读取了消息。这种方式需要用户主动交互,但能实时获取到用户已读的信号。
示例代码:
import { Markup } from 'telegraf'; // 发送带按钮的消息 ctx.telegram.sendMessage( ctx.chat.id, '请查看这条消息', Markup.inlineKeyboard([ Markup.button.callback('我已查看', 'mark_read') ]) ); // 监听按钮回调 bot.action('mark_read', (ctx) => { console.log('用户已读消息!'); ctx.answerCbQuery('已确认你已读消息'); });
内容的提问来源于stack exchange,提问作者Vince M

