mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:00:42 +00:00
fix(auto-reply): keep docking in direct chats
This commit is contained in:
@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/slash commands: send block-only slash command replies instead of dropping Slack block payloads with no plain-text fallback. Thanks @vincentkoc.
|
||||
- Telegram/messages: derive fallback text from interactive button/select labels before sending button-only payloads, so Telegram replies are not rejected as empty messages. Thanks @vincentkoc.
|
||||
- LINE/messages: send quick-reply-only payloads with fallback option text instead of accepting the payload and returning an empty delivery. Thanks @vincentkoc.
|
||||
- Auto-reply/docking: require `/dock-*` route switches to start from direct chats, so group or channel participants cannot reroute a shared session's future replies into a linked DM. Thanks @vincentkoc.
|
||||
- Gateway/agent: reject strict `openclaw agent --deliver` requests with missing delivery targets before starting the agent run, so users do not wait for a completed turn that cannot send anywhere. Thanks @vincentkoc.
|
||||
- Setup/import: honor non-interactive `--import-from` onboarding flags by running the migration import path instead of silently completing normal setup without importing anything. Thanks @vincentkoc.
|
||||
- Discord/voice: run voice-channel turns under a voice-output policy that hides the agent `tts` tool and asks for spoken reply text, so `/vc join` sessions synthesize and play agent replies instead of ending with `NO_REPLY`. Fixes #61536. Thanks @aounakram.
|
||||
|
||||
@@ -55,6 +55,7 @@ function buildDockParams(commandBody: string, ctxOverrides?: Partial<MsgContext>
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
OriginatingChannel: "telegram",
|
||||
ChatType: "direct",
|
||||
SenderId: "42",
|
||||
From: "42",
|
||||
...ctxOverrides,
|
||||
@@ -121,6 +122,25 @@ describe("handleDockCommand", () => {
|
||||
expect(params.sessionEntry?.lastChannel).toBe("telegram");
|
||||
});
|
||||
|
||||
it("rejects group-session docking before it can reroute replies to a linked DM", async () => {
|
||||
const params = buildDockParams("/dock-discord", {
|
||||
ChatType: "group",
|
||||
From: "telegram:group:-100123",
|
||||
To: "telegram:-100123",
|
||||
OriginatingTo: "telegram:-100123",
|
||||
SenderId: "42",
|
||||
});
|
||||
|
||||
const result = await handleDockCommand(params, true);
|
||||
|
||||
expect(result).toEqual({
|
||||
shouldContinue: false,
|
||||
reply: { text: "Cannot dock to discord: docking is only available from direct chats." },
|
||||
});
|
||||
expect(params.sessionEntry?.lastChannel).toBe("telegram");
|
||||
expect(params.sessionEntry?.lastTo).toBe("42");
|
||||
});
|
||||
|
||||
it("fails closed when no session entry can be persisted", async () => {
|
||||
const params = buildDockParams("/dock-discord");
|
||||
params.sessionEntry = undefined;
|
||||
|
||||
@@ -38,6 +38,10 @@ function resolveTargetChannelAccountId(
|
||||
return normalizeOptionalString(plugin?.config.defaultAccountId?.(params.cfg)) || "default";
|
||||
}
|
||||
|
||||
function isDirectDockSource(params: HandleCommandsParams): boolean {
|
||||
return normalizeLowercaseStringOrEmpty(params.ctx.ChatType) === "direct";
|
||||
}
|
||||
|
||||
function collectSourcePeerCandidates(params: HandleCommandsParams): string[] {
|
||||
return [
|
||||
params.ctx.NativeDirectUserId,
|
||||
@@ -126,6 +130,14 @@ export const handleDockCommand: CommandHandler = async (params, allowTextCommand
|
||||
reply: { text: `Already docked to ${targetChannel}.` },
|
||||
};
|
||||
}
|
||||
if (!isDirectDockSource(params)) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: {
|
||||
text: `Cannot dock to ${targetChannel}: docking is only available from direct chats.`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const sourceCandidates = buildSourceIdentityCandidates(params, sourceChannel);
|
||||
if (sourceCandidates.size === 0) {
|
||||
|
||||
Reference in New Issue
Block a user