Skip to content

[Bug] QQ 审批按钮点击后无任何反应:qqbot 网关连接未启动,INTERACTION_CREATE 从未路由到审批处理器 #304

Description

@INKSANSLPLR

[Bug] QQ 审批按钮点击后无任何反应:qqbot 网关连接未启动,INTERACTION_CREATE 从未路由到审批处理器a

修正版 —— 初版(字段缺失假设)经实测已排除,根因在更底层。

环境

项 值
OpenClaw 版本 2026.7.1-2
系统 Windows 10 / D:\nodejs\node.exe
网关进程 D:\nodejs\node_modules\openclaw\dist\index.js gateway --port 18789(core 包,PID 41692,启动 2026-08-13 20:39:50)
频道 qqbot(appId 1905295106,clientSecret 已配置,connected)
扩展代码 用户级 C:\Users\LPLR\.openclaw\extensions\qqbot\dist/(即仓库 tencent-connect/openclaw-qqbot)
全局审批策略 tools.exec.ask = "always"(保持不变,非本 bug 成因)

现象

QQ 私聊中,需要执行 shell 命令时龙虾下发审批按钮卡(✅ 允许一次 / ❌ 拒绝)。用户点击「✅ 允许一次」后:

  • 龙虾无任何反应,命令不执行;
  • 对应 run 在审计表里以 agent.run.finished status=blocked 结束(exec 仅 tool.action.started,无 finished);
  • 审批卡变成「死卡」——再点也无用。

同一审批若改在 OpenClaw 控制 UI(http://127.0.0.1:18789) 点击批准则正常执行。说明问题仅在 QQ 按钮路径,审批系统本身可用。

复现

  1. tools.exec.ask = "always",QQ 频道 connected。
  2. 在 QQ 私聊让龙虾执行任意需审批命令(触发 exec)。
  3. 龙虾在 QQ 下发审批按钮卡。
  4. 在 QQ 里点击「✅ 允许一次」。
  5. 观察:龙虾沉默;run 最终 blocked。

诊断过程与证据(已实测)

在 qqbot 扩展的多处加了写文件诊断埋点(调试日志 zh-patches/qqbot-approval-debug.log),重启网关后观察:

埋点位置 含义 是否触发
gateway-pJQppxe4.js 模块顶层 MODULE_LOADED 扩展模块被加载 ✅ 触发(证明扩展已加载)
index.js 顶层 INDEX_LOADED_USER 扩展入口加载 ✅ 触发
GatewayConnection.start() 首行 CONN_START 扩展网关连接被启动 ❌ 从未触发
ws.on("open") CONN_OPEN 扩展 ws 连接建立 ❌ 从未触发
ws.on("message") dispatch 扩展收到任意网关事件 ❌ 从未触发
createInteractionHandler() 顶部 interactionHandler 审批交互处理器被调用 ❌ 从未触发
handleMessage() 顶部 HANDLE_MESSAGE C2C 消息走扩展处理器 ❌ 从未触发

同时,audit_events 显示:QQ 私聊消息能正常触发 run(C2C 路径工作),但点击审批按钮的 run 全部以 blocked 结束。

根因

qqbot 审批交互的处理链路由扩展的 GatewayConnection 承载:

qqbotPlugin.gateway.startAccount(ctx)          // channel-D1UztsnG.js:1225
  → loadGatewayModule()                         // 动态加载 gateway-pJQppxe4.js
  → startGateway({ ..., onInteraction: handleInteraction, handleMessage })
      → new GatewayConnection({...}).start()     // gateway-pJQppxe4.js:6563
          → ws 连接 QQ 网关
          → ws.on("message") → dispatchEvent → 若 action==="interaction"
              → this.ctx.onInteraction(event)    // gateway-pJQppxe4.js:1583
                  → createInteractionHandler → authorizeApprovalButtonActor → 授权

证据表明:核心网关(core dist/index.js)并没有调用 qqbotPlugin.gateway.startAccount,因此:

  1. 扩展的 GatewayConnection 从未 start()(CONN_START/CONN_OPEN 不触发)→ 扩展的 ws 从不连接、从不接收事件;
  2. 扩展注册在自身 GatewayConnection 上的 onInteraction(审批处理器)从未被核心接线;
  3. C2C 消息由核心的另一条路径处理(能正常触发 run),但按钮点击的 INTERACTION_CREATE 不被任何处理器接收 → 审批卡永远 pending/blocked。

即:qqbot 通道的交互(按钮审批)处理器在运行时从未被启动/接线,这是 OpenClaw 核心与 qqbot 插件之间的集成缺陷,而非单纯的字段解析问题。

附:初版假设「resolveApprovalActorSenderIds 读不到发送者字段」已被排除——该函数本身确实只读 user_openid/group_member_openid(对 INTERACTION_CREATE 为空),但更上游的 handler 根本没被调用,所以字段问题不是当前阻断点。该字段加固仍建议作为后续改进(见下)。

影响范围

  • QQ 频道内无法就地批准任何 exec 审批卡(按钮必失败)。
  • 用户被迫改用控制 UI 批准,移动端体验断裂。
  • tools.exec.ask=always 安全规则本身无问题,不应为此关闭。

建议修复(两层)

P0(核心集成,必须修才能恢复按钮审批):

  • 核心网关在启动 qqbot 通道时应调用 qqbotPlugin.gateway.startAccount(或等价入口),确保 GatewayConnection 启动并把 onInteraction 接线到审批运行时(approval-handler-runtime 的 nativeRuntime.interactions 适配器)。
  • 或:qqbot 插件改为通过 startAccount 收到的 ctx 向核心注册 onInteraction,而非仅挂在自身 GatewayConnection 上。

P1(字段加固,P0 修好后生效):

  • 在 resolveApprovalActorSenderIds() 中,当 user_openid/group_member_openid 为空时,回退到 INTERACTION_CREATE 事件实际可用的发送者标识(event.openid、event.user_info.openid、event.data.user_openid、或递归扫描含 openid|user_id|sender_id 的键)。配合 channels.qqbot.allowFrom:["*"],事件一旦到达 handler 即可授权。

已尝试的本地补丁

  • 已对用户级 extensions/qqbot/dist/gateway-pJQppxe4.js 应用 resolveApprovalActorSenderIds 字段加固 + 诊断埋点,并重启加载(MODULE_LOADED 已确认)。
  • 因 P0(连接未启动)未解决,该加固尚无法被验证(handler 仍不被调用)。补丁本身无害,建议上游修复 P0 后保留。

临时绕过(可用)

  • 控制 UI 批准:电脑打开 http://127.0.0.1:18789/ 或 ClawX 桌面端,审批卡可正常点击批准,不影响 tools.exec.ask=always 安全规则。
  • 注:OpenClaw 的 exec 审批为全局策略(tools.exec.ask),无「按频道」维度,不能仅对 QQ 关掉审批而不影响其他频道。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions