mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:10:44 +00:00
fix: bound slack interactive button urls
This commit is contained in:
@@ -39,6 +39,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/commands: keep native command argument menus on select controls for encoded choice values up to Slack's option limit and truncate fallback button labels to Slack's button-text limit, so long valid choices no longer render invalid Slack blocks. Thanks @slackapi.
|
||||
- Agents/Codex: flush accepted debounced steering messages before normal app-server turn cleanup, so inbound follow-ups acknowledged as queued are not dropped when the turn completes before the debounce fires. Thanks @vincentkoc.
|
||||
- Slack/interactive replies: keep rendered buttons and selects within Slack Block Kit value and count limits, and align command argument select values with Slack's option limit, so overlong agent-authored choices no longer make Slack reject the whole block payload. Thanks @slackapi.
|
||||
- Slack/interactive replies: drop overlong Block Kit button URLs while preserving valid callback values, so malformed link buttons no longer make Slack reject the whole interactive reply. Thanks @slackapi.
|
||||
- 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.
|
||||
- Plugin SDK/testing: lazy-load TypeScript from the plugin test-contract runtime and add release checks for critical SDK contract entrypoint imports and bundle size, so published packages fail preflight before shipping ESM-incompatible or oversized contract helpers. Thanks @vincentkoc.
|
||||
|
||||
@@ -15,6 +15,7 @@ const SLACK_SECTION_TEXT_MAX = 3000;
|
||||
const SLACK_PLAIN_TEXT_MAX = 75;
|
||||
const SLACK_OPTION_VALUE_MAX = 75;
|
||||
const SLACK_BUTTON_VALUE_MAX = 2000;
|
||||
const SLACK_BUTTON_URL_MAX = 3000;
|
||||
const SLACK_STATIC_SELECT_OPTIONS_MAX = 100;
|
||||
const SLACK_ACTION_BLOCK_ELEMENTS_MAX = 25;
|
||||
|
||||
@@ -72,7 +73,11 @@ export function buildSlackInteractiveBlocks(interactive?: InteractiveReply): Sla
|
||||
button.value && isWithinSlackLimit(button.value, SLACK_BUTTON_VALUE_MAX)
|
||||
? button.value
|
||||
: undefined;
|
||||
if (!value && !button.url) {
|
||||
const url =
|
||||
button.url && isWithinSlackLimit(button.url, SLACK_BUTTON_URL_MAX)
|
||||
? button.url
|
||||
: undefined;
|
||||
if (!value && !url) {
|
||||
return [];
|
||||
}
|
||||
const style = resolveSlackButtonStyle(button.style);
|
||||
@@ -86,7 +91,7 @@ export function buildSlackInteractiveBlocks(interactive?: InteractiveReply): Sla
|
||||
emoji: true,
|
||||
},
|
||||
...(value ? { value } : {}),
|
||||
...(button.url ? { url: button.url } : {}),
|
||||
...(url ? { url } : {}),
|
||||
...(style ? { style } : {}),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -164,6 +164,34 @@ describe("buildSlackInteractiveBlocks", () => {
|
||||
expect(buttonBlock.elements?.[1]).not.toHaveProperty("value");
|
||||
});
|
||||
|
||||
it("drops Slack button URLs beyond Block Kit limits", () => {
|
||||
const validUrl = `https://example.com/${"a".repeat(2980)}`;
|
||||
const longUrl = `https://example.com/${"b".repeat(2981)}`;
|
||||
const blocks = buildSlackInteractiveBlocks({
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [
|
||||
{ label: "Allowed", url: validUrl },
|
||||
{ label: "Too long", url: longUrl },
|
||||
{ label: "Fallback action", value: "fallback", url: longUrl },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const buttonBlock = blocks[0] as {
|
||||
elements?: Array<{ value?: string; url?: string }>;
|
||||
};
|
||||
|
||||
expect(validUrl).toHaveLength(3000);
|
||||
expect(longUrl).toHaveLength(3001);
|
||||
expect(buttonBlock.elements).toHaveLength(2);
|
||||
expect(buttonBlock.elements?.[0]?.url).toBe(validUrl);
|
||||
expect(buttonBlock.elements?.[1]?.value).toBe("fallback");
|
||||
expect(buttonBlock.elements?.[1]).not.toHaveProperty("url");
|
||||
});
|
||||
|
||||
it("caps Slack actions blocks at the Block Kit element limit", () => {
|
||||
const blocks = buildSlackInteractiveBlocks({
|
||||
blocks: [
|
||||
|
||||
Reference in New Issue
Block a user