mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:40:43 +00:00
fix: drop overlong slack command values
This commit is contained in:
@@ -52,6 +52,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/commands: truncate native command argument-menu confirmation text to Slack's dialog limit, so long plugin arg names no longer make fallback buttons render invalid Block Kit payloads. Thanks @slackapi.
|
||||
- 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.
|
||||
- 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,7 @@ vi.mock("./slash-commands.runtime.js", () => {
|
||||
const reportLongCommand = { key: "reportlong", nativeName: "reportlong" };
|
||||
const reportLongButtonCommand = { key: "reportlongbutton", nativeName: "reportlongbutton" };
|
||||
const reportHugeButtonCommand = { key: "reporthugebutton", nativeName: "reporthugebutton" };
|
||||
const reportHugeValueCommand = { key: "reporthugevalue", nativeName: "reporthugevalue" };
|
||||
const unsafeConfirmCommand = { key: "unsafeconfirm", nativeName: "unsafeconfirm" };
|
||||
const longConfirmCommand = { key: "longconfirm", nativeName: "longconfirm" };
|
||||
const statusAliasCommand = { key: "status", nativeName: "status" };
|
||||
@@ -80,6 +81,9 @@ vi.mock("./slash-commands.runtime.js", () => {
|
||||
if (normalized === "reporthugebutton") {
|
||||
return reportHugeButtonCommand;
|
||||
}
|
||||
if (normalized === "reporthugevalue") {
|
||||
return reportHugeValueCommand;
|
||||
}
|
||||
if (normalized === "unsafeconfirm") {
|
||||
return unsafeConfirmCommand;
|
||||
}
|
||||
@@ -134,6 +138,12 @@ vi.mock("./slash-commands.runtime.js", () => {
|
||||
acceptsArgs: true,
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
name: "reporthugevalue",
|
||||
description: "ReportHugeValue",
|
||||
acceptsArgs: true,
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
name: "unsafeconfirm",
|
||||
description: "UnsafeConfirm",
|
||||
@@ -187,6 +197,12 @@ vi.mock("./slash-commands.runtime.js", () => {
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (params.command?.key === "reporthugevalue") {
|
||||
return resolvePeriodMenu(params, [
|
||||
{ value: "valid", label: "Valid" },
|
||||
{ value: "x".repeat(2500), label: "Overlong" },
|
||||
]);
|
||||
}
|
||||
if (params.command?.key === "reportcompact") {
|
||||
return resolvePeriodMenu(params, baseReportPeriodChoices);
|
||||
}
|
||||
@@ -466,6 +482,7 @@ describe("Slack native command argument menus", () => {
|
||||
let reportLongHandler: (args: unknown) => Promise<void>;
|
||||
let reportLongButtonHandler: (args: unknown) => Promise<void>;
|
||||
let reportHugeButtonHandler: (args: unknown) => Promise<void>;
|
||||
let reportHugeValueHandler: (args: unknown) => Promise<void>;
|
||||
let unsafeConfirmHandler: (args: unknown) => Promise<void>;
|
||||
let longConfirmHandler: (args: unknown) => Promise<void>;
|
||||
let agentStatusHandler: (args: unknown) => Promise<void>;
|
||||
@@ -490,6 +507,11 @@ describe("Slack native command argument menus", () => {
|
||||
"/reporthugebutton",
|
||||
"/reporthugebutton",
|
||||
);
|
||||
reportHugeValueHandler = requireHandler(
|
||||
harness.commands,
|
||||
"/reporthugevalue",
|
||||
"/reporthugevalue",
|
||||
);
|
||||
unsafeConfirmHandler = requireHandler(harness.commands, "/unsafeconfirm", "/unsafeconfirm");
|
||||
longConfirmHandler = requireHandler(harness.commands, "/longconfirm", "/longconfirm");
|
||||
agentStatusHandler = requireHandler(harness.commands, "/agentstatus", "/agentstatus");
|
||||
@@ -638,6 +660,24 @@ describe("Slack native command argument menus", () => {
|
||||
expect(actionBlocks.at(-1)?.elements).toHaveLength(5);
|
||||
});
|
||||
|
||||
it("drops fallback buttons whose encoded values exceed Slack's button value limit", async () => {
|
||||
const { respond } = await runCommandHandler(reportHugeValueHandler);
|
||||
expect(respond).toHaveBeenCalledTimes(1);
|
||||
const payload = respond.mock.calls[0]?.[0] as {
|
||||
blocks?: Array<{
|
||||
type: string;
|
||||
elements?: Array<{ text?: { text?: string }; value?: string }>;
|
||||
}>;
|
||||
};
|
||||
const actionBlocks = (payload.blocks ?? []).filter((block) => block.type === "actions");
|
||||
expect(actionBlocks).toHaveLength(1);
|
||||
expect(actionBlocks[0]?.elements).toHaveLength(1);
|
||||
expect(actionBlocks[0]?.elements?.[0]).toMatchObject({
|
||||
text: { text: "Valid" },
|
||||
});
|
||||
expect(actionBlocks[0]?.elements?.[0]?.value?.length).toBeLessThanOrEqual(2000);
|
||||
});
|
||||
|
||||
it("shows an overflow menu when choices fit compact range", async () => {
|
||||
const element = await getFirstActionElementFromCommand(reportCompactHandler);
|
||||
expect(element?.type).toBe("overflow");
|
||||
|
||||
@@ -56,6 +56,7 @@ const SLACK_COMMAND_ARG_SELECT_OPTIONS_MAX = 100;
|
||||
const SLACK_COMMAND_ARG_SELECT_OPTION_TEXT_MAX = 75;
|
||||
const SLACK_COMMAND_ARG_SELECT_OPTION_VALUE_MAX = 75;
|
||||
const SLACK_COMMAND_ARG_BUTTON_TEXT_MAX = 75;
|
||||
const SLACK_COMMAND_ARG_BUTTON_VALUE_MAX = 2000;
|
||||
const SLACK_COMMAND_ARG_CONFIRM_TEXT_MAX = 300;
|
||||
const SLACK_HEADER_TEXT_MAX = 150;
|
||||
const SLACK_COMMAND_ARG_CHROME_BLOCKS = 3;
|
||||
@@ -299,21 +300,24 @@ function buildSlackCommandArgMenuBlocks(params: {
|
||||
},
|
||||
]
|
||||
: encodedChoices.length <= SLACK_COMMAND_ARG_BUTTON_ROW_SIZE || !canUseStaticSelect
|
||||
? chunkItems(encodedChoices, SLACK_COMMAND_ARG_BUTTON_ROW_SIZE).map(
|
||||
(choices, rowIndex) => ({
|
||||
type: "actions",
|
||||
elements: choices.map((choice, colIndex) => ({
|
||||
type: "button",
|
||||
action_id: `${SLACK_COMMAND_ARG_ACTION_ID}_${rowIndex}_${colIndex}`,
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: truncateSlackText(choice.label, SLACK_COMMAND_ARG_BUTTON_TEXT_MAX),
|
||||
},
|
||||
value: choice.value,
|
||||
confirm: buildSlackArgMenuConfirm({ command: params.command, arg: params.arg }),
|
||||
})),
|
||||
}),
|
||||
)
|
||||
? chunkItems(
|
||||
encodedChoices.filter(
|
||||
(choice) => choice.value.length <= SLACK_COMMAND_ARG_BUTTON_VALUE_MAX,
|
||||
),
|
||||
SLACK_COMMAND_ARG_BUTTON_ROW_SIZE,
|
||||
).map((choices, rowIndex) => ({
|
||||
type: "actions",
|
||||
elements: choices.map((choice, colIndex) => ({
|
||||
type: "button",
|
||||
action_id: `${SLACK_COMMAND_ARG_ACTION_ID}_${rowIndex}_${colIndex}`,
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: truncateSlackText(choice.label, SLACK_COMMAND_ARG_BUTTON_TEXT_MAX),
|
||||
},
|
||||
value: choice.value,
|
||||
confirm: buildSlackArgMenuConfirm({ command: params.command, arg: params.arg }),
|
||||
})),
|
||||
}))
|
||||
: chunkItems(encodedChoices, SLACK_COMMAND_ARG_SELECT_OPTIONS_MAX).map(
|
||||
(choices, index) => ({
|
||||
type: "actions",
|
||||
|
||||
Reference in New Issue
Block a user