fix(slack): default unfurl_links to false for outbound messages

Slack link unfurls (inline message previews) are enabled by default
when unfurl_links is not explicitly set in chat.postMessage. This means
bot messages containing Slack message links or URLs automatically expand
into rich preview cards, which can be noisy in channels.

Default unfurl_links to false so outbound messages don't show inline
link previews unless the operator explicitly opts in via:

  channels.slack.unfurlLinks: true

unfurlMedia remains opt-in (only sent when explicitly configured).
This commit is contained in:
Kibi
2026-05-15 11:17:11 +00:00
committed by Peter Steinberger
parent b4f6cb29b8
commit cb695b0986
3 changed files with 7 additions and 4 deletions

View File

@@ -1282,7 +1282,7 @@ Primary reference: [Configuration reference - Slack](/gateway/config-channels#sl
- channel access: `groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention`
- threading/history: `replyToMode`, `replyToModeByChatType`, `thread.*`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
- delivery: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `streaming`, `streaming.nativeTransport`, `streaming.preview.toolProgress`
- unfurls: `unfurlLinks`, `unfurlMedia` for `chat.postMessage` link/media preview control
- unfurls: `unfurlLinks` (default: `false`), `unfurlMedia` for `chat.postMessage` link/media preview control
- ops/features: `configWrites`, `commands.native`, `slashCommand.*`, `actions.*`, `userToken`, `userTokenReadOnly`
</Accordion>

View File

@@ -128,7 +128,10 @@ function hasCustomIdentity(identity?: SlackSendIdentity): boolean {
function buildSlackUnfurlPayload(options?: SlackUnfurlOptions) {
return {
...(typeof options?.unfurlLinks === "boolean" ? { unfurl_links: options.unfurlLinks } : {}),
// Default unfurl_links to false so bot messages don't expand inline
// link previews (Slack message links, URLs, etc.) unless the operator
// explicitly opts in via `channels.slack.unfurlLinks: true`.
unfurl_links: options?.unfurlLinks ?? false,
...(typeof options?.unfurlMedia === "boolean" ? { unfurl_media: options.unfurlMedia } : {}),
};
}

View File

@@ -47,7 +47,7 @@ function requireLastPostMessagePayload(client: SlackUnfurlTestClient) {
}
describe("sendMessageSlack unfurl controls", () => {
it("omits Slack unfurl flags when config is unset", async () => {
it("defaults unfurl_links to false when config is unset", async () => {
const client = createSlackSendTestClient();
await sendMessageSlack("channel:C123", "https://example.com", {
@@ -58,7 +58,7 @@ describe("sendMessageSlack unfurl controls", () => {
expect(client.chat.postMessage).toHaveBeenCalledTimes(1);
const payload = requirePostMessagePayload(client);
expect("unfurl_links" in payload).toBe(false);
expect(payload.unfurl_links).toBe(false);
expect("unfurl_media" in payload).toBe(false);
});