mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 14:50:45 +00:00
fix: keep slack message controls
This commit is contained in:
@@ -76,6 +76,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/exec approvals: cap native approval metadata context to Slack's element and text limits, so large approval details no longer make Slack reject the approval card. Thanks @slackapi.
|
||||
- Slack/commands: cap native command argument-menu fallback rows to Slack's message block limit, so large plugin choice lists no longer make Slack reject the generated menu. Thanks @slackapi.
|
||||
- Slack/commands: drop fallback command argument buttons whose encoded values exceed Slack's button-value limit, so one oversized plugin choice no longer makes Slack reject the whole menu. Thanks @slackapi.
|
||||
- Slack/messages: merge message-tool presentation and interactive blocks on Slack sends, so buttons and selects are no longer dropped when a structured message body is also present. Thanks @slackapi.
|
||||
- Channels/WhatsApp: require Baileys outbound message ids before marking auto-replies delivered, so transcript text and ack reactions no longer make failed group replies look sent. Fixes #49225. Thanks @TinyTb.
|
||||
- CLI/update: scope packaged Node compile caches by OpenClaw version and install metadata, so global installs no longer reuse stale compiled chunks after package updates. Thanks @pashpashpash.
|
||||
- Channels/Voice call: keep pre-auth webhook in-flight limiting active when socket remote address metadata is missing, so slow-body requests from stripped-IP proxy paths still share the fallback bucket. (#74453) Thanks @davidangularme.
|
||||
|
||||
@@ -9,6 +9,45 @@ function createInvokeSpy() {
|
||||
}
|
||||
|
||||
describe("handleSlackMessageAction", () => {
|
||||
it("merges presentation and interactive blocks when sending", async () => {
|
||||
const invoke = createInvokeSpy();
|
||||
|
||||
await handleSlackMessageAction({
|
||||
providerId: "slack",
|
||||
ctx: {
|
||||
action: "send",
|
||||
cfg: {},
|
||||
params: {
|
||||
to: "channel:C1",
|
||||
message: "Deploy?",
|
||||
presentation: {
|
||||
blocks: [{ type: "text", text: "Deploy summary" }],
|
||||
},
|
||||
interactive: {
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [{ label: "Approve", value: "approve" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
invoke: invoke as never,
|
||||
});
|
||||
|
||||
const action = invoke.mock.calls[0]?.[0] as {
|
||||
blocks?: Array<{ type?: string; elements?: Array<{ value?: string }> }>;
|
||||
};
|
||||
expect(action.blocks).toEqual([
|
||||
expect.objectContaining({ type: "section" }),
|
||||
expect.objectContaining({
|
||||
type: "actions",
|
||||
elements: [expect.objectContaining({ value: "approve" })],
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("maps upload-file to the internal uploadFile action", async () => {
|
||||
const invoke = createInvokeSpy();
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ export async function handleSlackMessageAction(params: {
|
||||
const presentationBlocks = presentation
|
||||
? buildSlackPresentationBlocks(presentation)
|
||||
: undefined;
|
||||
const blocks = presentationBlocks?.length ? presentationBlocks : interactiveBlocks;
|
||||
const mergedBlocks = [...(presentationBlocks ?? []), ...(interactiveBlocks ?? [])];
|
||||
const blocks = mergedBlocks.length > 0 ? mergedBlocks : undefined;
|
||||
if (!content && !mediaUrl && !blocks) {
|
||||
throw new Error("Slack send requires message, blocks, or media.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user