You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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,核心是修改该用户的会话数据并触发场景切换逻辑。

  1. 确保会话可全局访问
    首先要配置持久化的会话存储(比如telegraf-session-local或Redis),这样才能跨上下文获取其他用户的会话数据。以telegraf-session-local为例,初始化后可以直接通过实例读写用户会话。

  2. 修改目标用户的会话场景字段
    Telegraf会在会话中用__scene字段存储当前场景信息,直接修改这个字段并保存会话即可更新用户的场景状态:

    // 假设你已初始化sessionStore实例
    const userSession = await sessionStore.get(userId);
    if (userSession) {
      // 更新为目标场景,可传入场景初始化状态
      userSession.__scene = {
        current: "winner",
        state: {}
      };
      await sessionStore.set(userId, userSession);
    }
    
  3. 触发用户场景切换生效
    修改会话后,若想让用户立即进入新场景并触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:23:17