mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix(slack): offset presentation controls after native blocks
Co-authored-by: openclaw-clawsweeper[bot] <280122609+openclaw-clawsweeper[bot]@users.noreply.github.com>
This commit is contained in:
@@ -186,7 +186,10 @@ export function buildSlackInteractiveBlocks(
|
||||
}).blocks;
|
||||
}
|
||||
|
||||
export function buildSlackPresentationBlocks(presentation?: MessagePresentation): SlackBlock[] {
|
||||
export function buildSlackPresentationBlocks(
|
||||
presentation?: MessagePresentation,
|
||||
options: SlackInteractiveBlockRenderOptions = {},
|
||||
): SlackBlock[] {
|
||||
if (!presentation) {
|
||||
return [];
|
||||
}
|
||||
@@ -229,6 +232,6 @@ export function buildSlackPresentationBlocks(presentation?: MessagePresentation)
|
||||
(block) => block.type === "buttons" || block.type === "select",
|
||||
),
|
||||
});
|
||||
blocks.push(...buildSlackInteractiveBlocks(interactive));
|
||||
blocks.push(...buildSlackInteractiveBlocks(interactive, options));
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,11 @@ function resolveSlackBlocks(payload: {
|
||||
| undefined;
|
||||
const nativeBlocks = parseSlackBlocksInput(slackData?.blocks) as SlackBlock[] | undefined;
|
||||
const renderedPresentation =
|
||||
slackData?.presentationBlocks ?? buildSlackPresentationBlocks(payload.presentation);
|
||||
slackData?.presentationBlocks ??
|
||||
buildSlackPresentationBlocks(
|
||||
payload.presentation,
|
||||
resolveSlackInteractiveBlockOffsets(nativeBlocks),
|
||||
);
|
||||
const previousBlocks = [...(nativeBlocks ?? []), ...renderedPresentation];
|
||||
const renderedInteractive = resolveRenderedInteractiveBlocks(payload.interactive, previousBlocks);
|
||||
const mergedBlocks = [...previousBlocks, ...(renderedInteractive ?? [])];
|
||||
@@ -147,16 +151,23 @@ export const slackOutbound: ChannelOutboundAdapter = {
|
||||
context: true,
|
||||
divider: true,
|
||||
},
|
||||
renderPresentation: ({ payload, presentation }) => ({
|
||||
...payload,
|
||||
channelData: {
|
||||
...payload.channelData,
|
||||
slack: {
|
||||
...(payload.channelData?.slack as Record<string, unknown> | undefined),
|
||||
presentationBlocks: buildSlackPresentationBlocks(presentation),
|
||||
renderPresentation: ({ payload, presentation }) => {
|
||||
const slackData = payload.channelData?.slack as Record<string, unknown> | undefined;
|
||||
const nativeBlocks = parseSlackBlocksInput(slackData?.blocks) as SlackBlock[] | undefined;
|
||||
return {
|
||||
...payload,
|
||||
channelData: {
|
||||
...payload.channelData,
|
||||
slack: {
|
||||
...slackData,
|
||||
presentationBlocks: buildSlackPresentationBlocks(
|
||||
presentation,
|
||||
resolveSlackInteractiveBlockOffsets(nativeBlocks),
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
sendPayload: async (ctx) => {
|
||||
const payload = {
|
||||
...ctx.payload,
|
||||
|
||||
@@ -94,6 +94,61 @@ describe("slackOutbound sendPayload", () => {
|
||||
await expect(run()).rejects.toThrow(/Slack blocks cannot exceed 50 items/i);
|
||||
expect(sendMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("offsets presentation controls against native Slack blocks before standalone interactive controls", async () => {
|
||||
const { run, sendMock, to } = createHarness({
|
||||
payload: {
|
||||
text: "Deploy?",
|
||||
channelData: {
|
||||
slack: {
|
||||
blocks: [
|
||||
{
|
||||
type: "actions",
|
||||
block_id: "openclaw_reply_buttons_1",
|
||||
elements: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
presentation: {
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [{ label: "Stage", value: "stage" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
interactive: {
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [{ label: "Approve", value: "approve" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(sendMock).toHaveBeenCalledWith(
|
||||
to,
|
||||
"Deploy?",
|
||||
expect.objectContaining({
|
||||
blocks: [
|
||||
expect.objectContaining({ block_id: "openclaw_reply_buttons_1" }),
|
||||
expect.objectContaining({
|
||||
block_id: "openclaw_reply_buttons_2",
|
||||
elements: [expect.objectContaining({ action_id: "openclaw:reply_button:2:1" })],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
block_id: "openclaw_reply_buttons_3",
|
||||
elements: [expect.objectContaining({ action_id: "openclaw:reply_button:3:1" })],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Slack outbound payload contract", () => {
|
||||
|
||||
Reference in New Issue
Block a user