diff --git a/extensions/slack/src/actions.ts b/extensions/slack/src/actions.ts index f1dbd45b9af..58ca16e9b9f 100644 --- a/extensions/slack/src/actions.ts +++ b/extensions/slack/src/actions.ts @@ -3,15 +3,13 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types"; import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime"; import { logVerbose } from "openclaw/plugin-sdk/runtime-env"; import { resolveSlackAccount } from "./accounts.js"; -import { buildSlackBlocksFallbackText } from "./blocks-fallback.js"; import { validateSlackBlocksArray } from "./blocks-input.js"; import { createSlackWebClient, getSlackWriteClient } from "./client.js"; -import { SLACK_TEXT_LIMIT } from "./limits.js"; +import { buildSlackEditTextPayload } from "./edit-text.js"; import { resolveSlackMedia } from "./monitor/media.js"; import type { SlackMediaResult } from "./monitor/media.js"; import { sendMessageSlack } from "./send.js"; import { resolveSlackBotToken } from "./token.js"; -import { truncateSlackText } from "./truncate.js"; export type SlackActionClientOpts = { cfg?: OpenClawConfig; @@ -232,13 +230,10 @@ export async function editSlackMessage( ) { const client = await getClient(opts, "write"); const blocks = opts.blocks == null ? undefined : validateSlackBlocksArray(opts.blocks); - const trimmedContent = content.trim(); await client.chat.update({ channel: channelId, ts: messageId, - text: - trimmedContent || - (blocks ? truncateSlackText(buildSlackBlocksFallbackText(blocks), SLACK_TEXT_LIMIT) : " "), + text: buildSlackEditTextPayload(content, blocks), ...(blocks ? { blocks } : {}), }); } diff --git a/extensions/slack/src/edit-text.ts b/extensions/slack/src/edit-text.ts new file mode 100644 index 00000000000..f265047413c --- /dev/null +++ b/extensions/slack/src/edit-text.ts @@ -0,0 +1,18 @@ +import type { Block, KnownBlock } from "@slack/web-api"; +import { buildSlackBlocksFallbackText } from "./blocks-fallback.js"; +import { SLACK_TEXT_LIMIT } from "./limits.js"; +import { truncateSlackText } from "./truncate.js"; + +export function buildSlackEditTextPayload( + content: string, + blocks?: (Block | KnownBlock)[], +): string { + const trimmedContent = content.trim(); + if (trimmedContent) { + return trimmedContent; + } + if (blocks?.length) { + return truncateSlackText(buildSlackBlocksFallbackText(blocks), SLACK_TEXT_LIMIT); + } + return " "; +} diff --git a/extensions/slack/src/monitor/message-handler/preview-finalize.test.ts b/extensions/slack/src/monitor/message-handler/preview-finalize.test.ts index 3a55406ada6..6bdb9365b22 100644 --- a/extensions/slack/src/monitor/message-handler/preview-finalize.test.ts +++ b/extensions/slack/src/monitor/message-handler/preview-finalize.test.ts @@ -108,4 +108,41 @@ describe("finalizeSlackPreviewEdit", () => { }), ).toBe("*Done*"); }); + + it("matches truncated fallback text for long blocks-only edit readback", async () => { + const longContextText = "a".repeat(3000); + const blocks = [ + { + type: "context", + elements: [ + { type: "mrkdwn", text: longContextText }, + { type: "mrkdwn", text: longContextText }, + { type: "mrkdwn", text: longContextText }, + ], + }, + ] as const; + const expectedText = __testing.buildExpectedSlackEditText({ + text: "", + blocks: blocks as unknown as Parameters< + typeof __testing.buildExpectedSlackEditText + >[0]["blocks"], + }); + const client = createClient({ + historyMessages: [{ ts: "171234.567", text: expectedText, blocks }], + }); + + expect(expectedText).toHaveLength(8000); + await expect( + __testing.didSlackPreviewEditApplyAfterError({ + client, + token: "xoxb-test", + channelId: "C123", + messageId: "171234.567", + text: "", + blocks: blocks as unknown as Parameters< + typeof __testing.didSlackPreviewEditApplyAfterError + >[0]["blocks"], + }), + ).resolves.toBe(true); + }); }); diff --git a/extensions/slack/src/monitor/message-handler/preview-finalize.ts b/extensions/slack/src/monitor/message-handler/preview-finalize.ts index b970e67daf3..12576663446 100644 --- a/extensions/slack/src/monitor/message-handler/preview-finalize.ts +++ b/extensions/slack/src/monitor/message-handler/preview-finalize.ts @@ -1,7 +1,7 @@ import type { Block, KnownBlock, WebClient } from "@slack/web-api"; import { logVerbose } from "openclaw/plugin-sdk/runtime-env"; import { editSlackMessage } from "../../actions.js"; -import { buildSlackBlocksFallbackText } from "../../blocks-fallback.js"; +import { buildSlackEditTextPayload } from "../../edit-text.js"; import { normalizeSlackOutboundText } from "../../format.js"; type SlackReadbackMessage = { @@ -14,14 +14,7 @@ function buildExpectedSlackEditText(params: { text: string; blocks?: (Block | KnownBlock)[]; }): string { - const trimmed = normalizeSlackOutboundText(params.text.trim()); - if (trimmed) { - return trimmed; - } - if (params.blocks?.length) { - return buildSlackBlocksFallbackText(params.blocks); - } - return " "; + return buildSlackEditTextPayload(params.text, params.blocks); } function blocksMatch(expected?: (Block | KnownBlock)[], actual?: unknown[]): boolean {