如何用node-telegram-bot-api实现消息反应更新及群组游戏功能
Telegram机器人实现「反应收集+定向启动游戏」方案
你的代码问题所在
你当前的代码只监听了message事件,而消息反应更新属于message_reaction事件,所以根本捕获不到反应数据。另外,在message事件里调用getUpdates是重复处理更新的错误写法——bot的事件监听本身就是基于getUpdates(或webhook)的,这么做会导致更新重复读取、逻辑混乱。
正确实现步骤
1. 监听消息反应事件,收集用户ID
用机器人库的message_reaction事件捕获用户对目标消息的反应,把参与反应的用户ID存起来(用Set避免重复记录同一个用户)。
2. 存储已反应用户
测试阶段可以用内存Set,长期运行的机器人建议用数据库(如Redis、MongoDB)持久化数据。
3. 触发游戏并定向发送给已反应用户
监听指定指令(如/start_game),收到指令后遍历存储的用户ID,给每个用户发送游戏启动内容。
完整示例代码(基于node-telegram-bot-api)
const TelegramBot = require('node-telegram-bot-api'); const token = '你的机器人Token'; const bot = new TelegramBot(token, { polling: true }); // 存储已反应的用户ID(内存存储,重启会清空,生产环境换数据库) const reactedUsers = new Set(); // 记录需要收集反应的目标消息ID let targetMessageId = null; // 触发收集反应的指令 bot.onText(/\/start_collect/, (msg) => { const chatId = msg.chat.id; bot.sendMessage(chatId, "点击反应按钮参与游戏!").then((sentMsg) => { targetMessageId = sentMsg.message_id; }); }); // 监听消息反应事件 bot.on('message_reaction', (update) => { const { message, new_reaction } = update.message_reaction; // 只处理目标消息的反应,排除机器人自身 if (message.message_id !== targetMessageId || message.from?.is_bot) return; // 提取并存储反应用户ID new_reaction.forEach((reaction) => { if (reaction.user) { reactedUsers.add(reaction.user.id); console.log(`用户 ${reaction.user.id} 已参与`); } }); }); // 启动游戏,仅发给已反应用户 bot.onText(/\/start_game/, (msg) => { const chatId = msg.chat.id; if (reactedUsers.size === 0) { bot.sendMessage(chatId, "还没有用户参与,请先发送/start_collect收集参与者!"); return; } // 给每个参与者发送游戏内容 reactedUsers.forEach((userId) => { bot.sendMessage(userId, "游戏开始!这是你的专属游戏内容..."); }); // 可选:清空数据,准备下一轮 reactedUsers.clear(); targetMessageId = null; });
关键说明
- 权限配置:确保机器人在群组中有「读取消息」「发送消息」权限,否则无法捕获反应或发送游戏内容。
- 反应去重:用Set存储用户ID,避免同一个用户多次反应被重复记录。
- 生产环境优化:内存存储重启会丢失数据,建议用数据库持久化用户信息。
内容的提问来源于stack exchange,提问作者Mohammad Sayem
相关产品推荐
相关产品推荐

