openclaw - 💡(How to fix) Fix 多个 outbound 消息路径导致 message hook 不完整触发的问题 [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#50122Fetched 2026-04-08 00:58:57
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
closed ×1locked ×1

Fix Action

Fix / Workaround

bot-message-dispatch.ts 调用 deliverReplies 时传入 sessionKeyForInternalHooks

// extensions/telegram/src/bot-message-dispatch.ts
await deliverReplies({
  // ...existing params
  sessionKeyForInternalHooks: ctxPayload.SessionKey,
  hookRunner: /* 通过 runtime 或全局 hookRunner 获取 */,
});
  • extensions/telegram/src/bot/delivery.replies.tsTelegram 发送层(漏录位置)
  • extensions/telegram/src/bot-message-dispatch.ts — 调用 deliverReplies 处
  • src/infra/outbound/deliver.ts — deliverOutboundPayloads(参照实现)
  • src/infra/outbound/outbound-send-service.ts — plugin sends,另有 gap
  • workspace/hooks/conversation-stream/handler.ts — 受影响的 hook

Code Example

// extensions/telegram/src/bot-message-dispatch.ts
await deliverReplies({
  // ...existing params
  sessionKeyForInternalHooks: ctxPayload.SessionKey,
  hookRunner: /* 通过 runtime 或全局 hookRunner 获取 */,
});
RAW_BUFFERClick to expand / collapse

问题描述

当前 OpenClaw 存在多条独立的 outbound 消息发送路径,这些路径与 message:sent / message_sent hook 的触发之间没有统一覆盖,导致部分出站消息无法被 internal hook 或 plugin hook 感知。

已确认的漏录场景:Telegram DM 中 agent 直接文本回复(如「清理完毕 ✅」)未落入 conversation-stream workspace hook 的 JSONL 记录中。

根因分析

出站消息路径现状

路径源码位置message:sent internal hookmessage_sent plugin hook
deliverOutboundPayloads(Core)src/infra/outbound/deliver.ts✅ 需 sessionKey 非空
deliverReplies(Telegram 内部)extensions/telegram/src/bot/delivery.replies.ts❌ sessionKey 未传入❌ hookRunner 未传入
outbound-send-service(plugin tool)src/infra/outbound/outbound-send-service.ts✅ 有条件Gap
respond 回调(RPC)src/gateway/server-methods/agent.ts❌ 不触发

关键问题

  1. deliverReplies 路径:调用时未传入 sessionKeyForInternalHookshookRunner,导致 emitMessageSentHooks() 内部条件判断失败,hook 永远不触发
  2. 架构不统一:deliverReplies 和 deliverOutboundPayloads 功能高度重叠但未共用抽象,channel 实现各自为政
  3. plugin message_sent gap:outbound-send-service 中 plugin-handled 路径无法触发 plugin hook(已有记录但未修复)

复现步骤

  1. 配置 conversation-stream workspace hook(监听 message:sent
  2. 通过 Telegram DM 向 bot 发送消息
  3. Bot agent 直接文本回复(不经 message tool)
  4. 观察 memory/conversations/telegram__<peer>/<date>.jsonl — outbound 消息未落盘

影响范围

  • conversation-stream hook:outbound 消息漏录,导致会话历史不完整
  • 所有依赖 message:sent / message_sent hook 的插件:可能丢失发送事件

修复建议

方案 A(最小改动)

bot-message-dispatch.ts 调用 deliverReplies 时传入 sessionKeyForInternalHooks

// extensions/telegram/src/bot-message-dispatch.ts
await deliverReplies({
  // ...existing params
  sessionKeyForInternalHooks: ctxPayload.SessionKey,
  hookRunner: /* 通过 runtime 或全局 hookRunner 获取 */,
});

方案 B(架构级)

引入统一 OutboundDeliveryObserver,所有 channel 发送路径最终都调用一次 observer.notify(),Hook 统一挂在这层,不再依赖各路径自行触发。

相关文件

  • extensions/telegram/src/bot/delivery.replies.tsTelegram 发送层(漏录位置)
  • extensions/telegram/src/bot-message-dispatch.ts — 调用 deliverReplies 处
  • src/infra/outbound/deliver.ts — deliverOutboundPayloads(参照实现)
  • src/infra/outbound/outbound-send-service.ts — plugin sends,另有 gap
  • workspace/hooks/conversation-stream/handler.ts — 受影响的 hook

标签

bug, hooks, telegram, architecture

extent analysis

Fix Plan

To fix the issue of outbound messages not being recorded in the conversation-stream workspace hook, we can follow one of the suggested approaches:

Approach A: Minimal Change

Modify the bot-message-dispatch.ts file to pass sessionKeyForInternalHooks when calling deliverReplies:

// extensions/telegram/src/bot-message-dispatch.ts
await deliverReplies({
  // ...existing params
  sessionKeyForInternalHooks: ctxPayload.SessionKey,
  hookRunner: /* obtain from runtime or global hookRunner */,
});

Approach B: Architectural Change

Introduce a unified OutboundDeliveryObserver that all channel sending paths call, and attach hooks to this layer:

// src/infra/outbound/outbound-delivery-observer.ts
class OutboundDeliveryObserver {
  private observers: ((message: any) => void)[];

  public notify(message: any) {
    this.observers.forEach((observer) => observer(message));
  }

  public addObserver(observer: (message: any) => void) {
    this.observers.push(observer);
  }
}

// usage
const observer = new OutboundDeliveryObserver();
observer.addObserver((message) => {
  // trigger message:sent hook
});

Then, modify all sending paths to call observer.notify():

// extensions/telegram/src/bot/delivery.replies.ts
observer.notify(message);

// src/infra/outbound/deliver.ts
observer.notify(message);

// src/infra/outbound/outbound-send-service.ts
observer.notify(message);

Verification

To verify the fix, follow these steps:

  1. Configure the conversation-stream workspace hook to listen for message:sent.
  2. Send a message to the bot via Telegram DM.
  3. The bot agent responds directly with a text message.
  4. Check the memory/conversations/telegram__<peer>/<date>.jsonl file for the outbound message.

Extra Tips

  • Ensure that all sending paths are modified to call the unified OutboundDeliveryObserver.
  • Test the fix thoroughly to ensure that all outbound messages are being recorded correctly.
  • Consider implementing additional logging or monitoring to detect any future issues with message recording.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix 多个 outbound 消息路径导致 message hook 不完整触发的问题 [1 participants]