fix(auto-reply): keep docking in direct chats · openclaw/openclaw@4f02a57
vincentkoc
·
2026-05-01
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
|
35 | 35 | - Slack/slash commands: send block-only slash command replies instead of dropping Slack block payloads with no plain-text fallback. Thanks @vincentkoc. |
36 | 36 | - 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. |
37 | 37 | - LINE/messages: send quick-reply-only payloads with fallback option text instead of accepting the payload and returning an empty delivery. Thanks @vincentkoc. |
| 38 | +- 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. |
38 | 39 | - 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. |
39 | 40 | - 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. |
40 | 41 | - 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. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -55,6 +55,7 @@ function buildDockParams(commandBody: string, ctxOverrides?: Partial<MsgContext>
|
55 | 55 | Provider: "telegram", |
56 | 56 | Surface: "telegram", |
57 | 57 | OriginatingChannel: "telegram", |
| 58 | +ChatType: "direct", |
58 | 59 | SenderId: "42", |
59 | 60 | From: "42", |
60 | 61 | ...ctxOverrides, |
@@ -121,6 +122,25 @@ describe("handleDockCommand", () => {
|
121 | 122 | expect(params.sessionEntry?.lastChannel).toBe("telegram"); |
122 | 123 | }); |
123 | 124 | |
| 125 | +it("rejects group-session docking before it can reroute replies to a linked DM", async () => { |
| 126 | +const params = buildDockParams("/dock-discord", { |
| 127 | +ChatType: "group", |
| 128 | +From: "telegram:group:-100123", |
| 129 | +To: "telegram:-100123", |
| 130 | +OriginatingTo: "telegram:-100123", |
| 131 | +SenderId: "42", |
| 132 | +}); |
| 133 | + |
| 134 | +const result = await handleDockCommand(params, true); |
| 135 | + |
| 136 | +expect(result).toEqual({ |
| 137 | +shouldContinue: false, |
| 138 | +reply: { text: "Cannot dock to discord: docking is only available from direct chats." }, |
| 139 | +}); |
| 140 | +expect(params.sessionEntry?.lastChannel).toBe("telegram"); |
| 141 | +expect(params.sessionEntry?.lastTo).toBe("42"); |
| 142 | +}); |
| 143 | + |
124 | 144 | it("fails closed when no session entry can be persisted", async () => { |
125 | 145 | const params = buildDockParams("/dock-discord"); |
126 | 146 | params.sessionEntry = undefined; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -38,6 +38,10 @@ function resolveTargetChannelAccountId(
|
38 | 38 | return normalizeOptionalString(plugin?.config.defaultAccountId?.(params.cfg)) || "default"; |
39 | 39 | } |
40 | 40 | |
| 41 | +function isDirectDockSource(params: HandleCommandsParams): boolean { |
| 42 | +return normalizeLowercaseStringOrEmpty(params.ctx.ChatType) === "direct"; |
| 43 | +} |
| 44 | + |
41 | 45 | function collectSourcePeerCandidates(params: HandleCommandsParams): string[] { |
42 | 46 | return [ |
43 | 47 | params.ctx.NativeDirectUserId, |
@@ -126,6 +130,14 @@ export const handleDockCommand: CommandHandler = async (params, allowTextCommand
|
126 | 130 | reply: { text: `Already docked to ${targetChannel}.` }, |
127 | 131 | }; |
128 | 132 | } |
| 133 | +if (!isDirectDockSource(params)) { |
| 134 | +return { |
| 135 | +shouldContinue: false, |
| 136 | +reply: { |
| 137 | +text: `Cannot dock to ${targetChannel}: docking is only available from direct chats.`, |
| 138 | +}, |
| 139 | +}; |
| 140 | +} |
129 | 141 | |
130 | 142 | const sourceCandidates = buildSourceIdentityCandidates(params, sourceChannel); |
131 | 143 | if (sourceCandidates.size === 0) { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。