mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 13:26:04 -06:00
fix(channels): route direct DM replies to sender (#124837)
Default direct-message reply context to the authenticated sender address so targetless Reef and Nostr replies do not resolve to the local recipient.
This commit is contained in:
committed by
GitHub
parent
4aafed1f4a
commit
313fcf1dba
@@ -199,8 +199,11 @@ describe("dispatchInboundDirectDm", () => {
|
||||
onDispatchError: vi.fn(),
|
||||
});
|
||||
|
||||
expect(vi.mocked(buildChannelInboundEventContext).mock.calls.at(-1)?.[0].channelIngress).toBe(
|
||||
"unsupported",
|
||||
);
|
||||
const contextParams = vi.mocked(buildChannelInboundEventContext).mock.calls.at(-1)?.[0];
|
||||
expect(contextParams?.channelIngress).toBe("unsupported");
|
||||
expect(contextParams?.reply).toEqual({
|
||||
to: "reef:bot-1",
|
||||
originatingTo: "reef:peer-1",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,7 +101,7 @@ async function buildDirectDmContext(
|
||||
},
|
||||
reply: {
|
||||
to: params.recipientAddress,
|
||||
originatingTo: params.originatingTo ?? params.recipientAddress,
|
||||
originatingTo: params.originatingTo ?? params.senderAddress,
|
||||
},
|
||||
message: {
|
||||
body,
|
||||
@@ -232,7 +232,7 @@ export async function dispatchInboundDirectDmWithRuntime(
|
||||
CommandAuthorized: params.commandAuthorized,
|
||||
...(params.inboundAccessAuthorized === true ? { InboundAccessAuthorized: true } : {}),
|
||||
OriginatingChannel: params.originatingChannel ?? params.channel,
|
||||
OriginatingTo: params.originatingTo ?? params.recipientAddress,
|
||||
OriginatingTo: params.originatingTo ?? params.senderAddress,
|
||||
NativeDirectUserId: params.peer.id,
|
||||
...params.extraContext,
|
||||
});
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
* Tests direct-message guard policy helpers exposed through the SDK.
|
||||
*/
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { resolveOriginMessageTo } from "../auto-reply/reply/origin-routing.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveImplicitMessageActionTarget } from "../infra/outbound/message-action-normalization.js";
|
||||
import {
|
||||
createDirectDmPreCryptoGuardPolicy,
|
||||
createPreCryptoDirectDmAuthorizer,
|
||||
@@ -242,16 +244,16 @@ describe("channel-inbound direct-message helpers", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("dispatches direct DMs through the standard route/session/reply pipeline", async () => {
|
||||
it("routes a targetless contextual reply to the inbound Reef peer", async () => {
|
||||
const { recordInboundSession, dispatchReplyWithBufferedBlockDispatcher, runtime } =
|
||||
createDirectDmRuntime();
|
||||
const deliver = vi.fn(async () => {});
|
||||
const channelIngress = await resolveStableChannelMessageIngress({
|
||||
channelId: "nostr",
|
||||
channelId: "reef",
|
||||
accountId: "default",
|
||||
subject: { stableId: "sender-1" },
|
||||
conversation: { kind: "direct", id: "sender-1" },
|
||||
dmPolicy: "open",
|
||||
subject: { stableId: "clawstudio" },
|
||||
conversation: { kind: "direct", id: "clawstudio" },
|
||||
dmPolicy: "allowlist",
|
||||
});
|
||||
|
||||
const result = await dispatchInboundDirectDmWithRuntime({
|
||||
@@ -260,14 +262,14 @@ describe("channel-inbound direct-message helpers", () => {
|
||||
session: { store: { type: "jsonl" } },
|
||||
} as never,
|
||||
runtime,
|
||||
channel: "nostr",
|
||||
channelLabel: "Nostr",
|
||||
channel: "reef",
|
||||
channelLabel: "Reef",
|
||||
accountId: "default",
|
||||
peer: { kind: "direct", id: "sender-1" },
|
||||
senderId: "sender-1",
|
||||
senderAddress: "nostr:sender-1",
|
||||
recipientAddress: "nostr:bot-1",
|
||||
conversationLabel: "sender-1",
|
||||
peer: { kind: "direct", id: "clawstudio" },
|
||||
senderId: "clawstudio",
|
||||
senderAddress: "reef:clawstudio",
|
||||
recipientAddress: "reef:roboclaw",
|
||||
conversationLabel: "@clawstudio's agent",
|
||||
rawBody: "hello world",
|
||||
messageId: "event-123",
|
||||
extraContext: {
|
||||
@@ -284,19 +286,26 @@ describe("channel-inbound direct-message helpers", () => {
|
||||
|
||||
expect(result.route.agentId).toBe("agent-main");
|
||||
expect(result.route.accountId).toBe("default");
|
||||
expect(result.route.sessionKey).toBe("dm:sender-1");
|
||||
expect(result.route.sessionKey).toBe("dm:clawstudio");
|
||||
expect(result.storePath).toBe("/tmp/direct-dm-session-store");
|
||||
expect(result.ctxPayload.Body).toBe("env:hello world");
|
||||
expect(result.ctxPayload.BodyForAgent).toBe("hello world");
|
||||
expect(result.ctxPayload.From).toBe("nostr:sender-1");
|
||||
expect(result.ctxPayload.To).toBe("nostr:bot-1");
|
||||
expect(result.ctxPayload.SenderId).toBe("sender-1");
|
||||
expect(result.ctxPayload.From).toBe("reef:clawstudio");
|
||||
expect(result.ctxPayload.To).toBe("reef:roboclaw");
|
||||
expect(result.ctxPayload.SenderId).toBe("clawstudio");
|
||||
expect(result.ctxPayload.MessageSid).toBe("event-123");
|
||||
expect(result.ctxPayload.ReplyToId).toBe("event-parent");
|
||||
expect(result.ctxPayload.MessageThreadId).toBe("thread-7");
|
||||
expect(result.ctxPayload.NativeDirectUserId).toBe("sender-1");
|
||||
expect(result.ctxPayload.OriginatingTo).toBe("nostr:bot-1");
|
||||
expect(result.ctxPayload.NativeDirectUserId).toBe("clawstudio");
|
||||
expect(result.ctxPayload.OriginatingTo).toBe("reef:clawstudio");
|
||||
expect(result.ctxPayload.CommandAuthorized).toBe(true);
|
||||
const currentChannelId = resolveOriginMessageTo({
|
||||
originatingTo: result.ctxPayload.OriginatingTo,
|
||||
to: result.ctxPayload.To,
|
||||
});
|
||||
expect(
|
||||
resolveImplicitMessageActionTarget({ currentChannelId, currentChannelProvider: "reef" }),
|
||||
).toBe("reef:clawstudio");
|
||||
expect(recordInboundSession).toHaveBeenCalledTimes(1);
|
||||
expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledTimes(1);
|
||||
expect(deliver).toHaveBeenCalledWith({ text: "reply text" });
|
||||
|
||||
Reference in New Issue
Block a user