如何在Telegraf.js中实现管理员批准后强制切换用户Scene?
问题:如何在管理员批准用户答案后强制切换用户的Scene?
我正在开发一款游戏机器人,流程是用户回答问题后,管理员对答案进行批准或拒绝操作。现在需要实现:当管理员批准用户的答案时,强制将该用户当前的Scene从"answering"切换到指定场景(比如"winner")。
现有代码逻辑:
用户处于"answering"场景发送消息时,消息会转发给管理员,附带批准/拒绝按钮:
const gameButtons = [ [ { text: `✅ approve`, callback_data: `gTo:appG/uId=${ctx.state.userId}` }, { text: `❌ reject`, callback_data: `gTo:rejG/uId=${ctx.state.userId}` }, ], ]; await ctx.telegram.sendMessage(ctx.state.chatTo, `User answer is: ${ctx.message.text}`, { reply_markup: JSON.stringify({ inline_keyboard: gameButtons }), });
管理员点击批准按钮后的处理逻辑框架如下,目前需要补充切换用户Scene的实现:
const approveQuestion = async ({ ctx, text }) => { const [, user] = text.split("/"); const [, userId] = user.split("="); //somehow change users scene to answered await changeUserScene("winner", userId); await ctx.telegram.sendMessage(userId, "It is right answer"); };
可行实现方案
基于Telegraf框架的实现(适配你的代码风格)
从代码来看你使用的是Telegraf框架,它的Scene系统依赖用户会话(session)存储场景状态,要强制切换其他用户的Scene,核心是修改该用户的会话数据并触发场景切换逻辑。
确保会话可全局访问
首先要配置持久化的会话存储(比如telegraf-session-local或Redis),这样才能跨上下文获取其他用户的会话数据。以telegraf-session-local为例,初始化后可以直接通过实例读写用户会话。修改目标用户的会话场景字段
Telegraf会在会话中用__scene字段存储当前场景信息,直接修改这个字段并保存会话即可更新用户的场景状态:// 假设你已初始化sessionStore实例 const userSession = await sessionStore.get(userId); if (userSession) { // 更新为目标场景,可传入场景初始化状态 userSession.__scene = { current: "winner", state: {} }; await sessionStore.set(userId, userSession); }触发用户场景切换生效
修改会话后,若想让用户立即进入新场景并触发enter钩子,可以给用户发送一个轻量的操作(比如输入状态提示),触发bot处理该用户的更新:await ctx.telegram.sendChatAction(userId, "typing");此时bot会读取用户最新的会话数据,自动切换到"winner"场景。
完整批准逻辑示例
const approveQuestion = async ({ ctx, text }) => { const [, user] = text.split("/"); const [, userId] = user.split("="); // 获取并更新用户会话 const userSession = await ctx.sessionStore.get(userId); if (userSession) { userSession.__scene = { current: "winner", state: {} }; await ctx.sessionStore.set(userId, userSession); // 触发场景切换并通知用户 await ctx.telegram.sendChatAction(userId, "typing"); await ctx.telegram.sendMessage(userId, "It is right answer"); } else { await ctx.answerCbQuery("未找到该用户会话"); } };
通用思路(不依赖框架)
如果你的bot并非基于Telegraf,核心逻辑一致:
- 将用户的Scene状态存储在全局可访问的位置(数据库、Redis等)
- 批准时直接更新该用户对应的Scene状态记录
- 若需要立即生效,主动给用户发送触发消息,让bot读取最新状态并切换场景
内容的提问来源于stack exchange,提问作者Ashot Khanamiryan
相关产品推荐
相关产品推荐

