From 378e18b75bf4224ac4d5d5bdee1eb2f5176a98c4 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 16 Feb 2026 12:20:09 -0500 Subject: [PATCH] Slack: support blocks in plugin edit action --- src/channels/plugins/actions/actions.test.ts | 71 ++++++++++++++++++++ src/plugin-sdk/slack-message-actions.ts | 9 ++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/channels/plugins/actions/actions.test.ts b/src/channels/plugins/actions/actions.test.ts index de9aa4c4e..ee134f650 100644 --- a/src/channels/plugins/actions/actions.test.ts +++ b/src/channels/plugins/actions/actions.test.ts @@ -593,4 +593,75 @@ describe("slack actions adapter", () => { ).rejects.toThrow(/blocks must be valid JSON/i); expect(handleSlackAction).not.toHaveBeenCalled(); }); + + it("forwards blocks JSON for edit", async () => { + const cfg = { channels: { slack: { botToken: "tok" } } } as OpenClawConfig; + const actions = createSlackActions("slack"); + + await actions.handleAction?.({ + channel: "slack", + action: "edit", + cfg, + params: { + channelId: "C1", + messageId: "171234.567", + message: "", + blocks: JSON.stringify([{ type: "divider" }]), + }, + }); + + const [params] = handleSlackAction.mock.calls[0] ?? []; + expect(params).toMatchObject({ + action: "editMessage", + channelId: "C1", + messageId: "171234.567", + content: "", + blocks: [{ type: "divider" }], + }); + }); + + it("forwards blocks arrays for edit", async () => { + const cfg = { channels: { slack: { botToken: "tok" } } } as OpenClawConfig; + const actions = createSlackActions("slack"); + + await actions.handleAction?.({ + channel: "slack", + action: "edit", + cfg, + params: { + channelId: "C1", + messageId: "171234.567", + message: "", + blocks: [{ type: "section", text: { type: "mrkdwn", text: "updated" } }], + }, + }); + + const [params] = handleSlackAction.mock.calls[0] ?? []; + expect(params).toMatchObject({ + action: "editMessage", + channelId: "C1", + messageId: "171234.567", + content: "", + blocks: [{ type: "section", text: { type: "mrkdwn", text: "updated" } }], + }); + }); + + it("rejects edit when both message and blocks are missing", async () => { + const cfg = { channels: { slack: { botToken: "tok" } } } as OpenClawConfig; + const actions = createSlackActions("slack"); + + await expect( + actions.handleAction?.({ + channel: "slack", + action: "edit", + cfg, + params: { + channelId: "C1", + messageId: "171234.567", + message: "", + }, + }), + ).rejects.toThrow(/edit requires message or blocks/i); + expect(handleSlackAction).not.toHaveBeenCalled(); + }); }); diff --git a/src/plugin-sdk/slack-message-actions.ts b/src/plugin-sdk/slack-message-actions.ts index 522aab339..0672c8d6d 100644 --- a/src/plugin-sdk/slack-message-actions.ts +++ b/src/plugin-sdk/slack-message-actions.ts @@ -130,13 +130,18 @@ export async function handleSlackMessageAction(params: { const messageId = readStringParam(actionParams, "messageId", { required: true, }); - const content = readStringParam(actionParams, "message", { required: true }); + const content = readStringParam(actionParams, "message", { allowEmpty: true }); + const blocks = readSlackBlocksParam(actionParams); + if (!content && !blocks) { + throw new Error("Slack edit requires message or blocks."); + } return await invoke( { action: "editMessage", channelId: resolveChannelId(), messageId, - content, + content: content ?? "", + blocks, accountId, }, cfg,