@chat-adapter/slack
4.43.0 · 19 Oct 2026MIT672.1k / weekRepositoryHomepagenpmAtom feed
60 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
4.43.0
19 Oct 20267881071: Stop treating a bot reference as a mention when the rendered message shows it only as text. Slack sends an
app_mentionevent for the bot's<@U…>token anywhere in a message'stextfield, including inside inline code or a code block, even when the message shows no mention. The adapter now reportsisMention: falsefor these messages, so they no longer reachonNewMention.When an
app_mentiondoesn't reference the bot's known user ID, the adapter treats it as a mention only if the rendered message shows a mention of some user outside code. This covers theW…IDs that Enterprise Grid workspaces can use for the bot. The same rule now applies when the bot user ID hasn't been resolved yet, where the adapter previously treated everyapp_mentionas a mention.For messages whose blocks are Block Kit rather than
rich_text, such as a header or section posted by an integration, the adapter now reads a bot token intextoutside code as a mention when the blocks don't show the bot. This applies to bothapp_mentionandmessageevents, so the two events for the same message are classified the same way.48bb905: Read the body of a Block Kit message from its blocks. When a message carries blocks, Slack renders them and uses
textonly as the notification fallback, somessage.textandmessage.formattedcould miss content an app or workflow placed in the blocks, including the request in a mention that reachedonNewMention. When every block is asection,header,context,image,divider,actions, or table block, the text in those blocks now forms the body in block order, with tables in place and links frommrkdwntext inmessage.links. Messages with any other block type, including therich_textblocks a Slack client sends, keep usingtext, so content the adapter can't render still reaches the message.
Patch Changes
7881071: Stop treating a bot reference as a mention when the rendered message shows it only as text. Slack sends an
app_mentionevent for the bot's<@U…>token anywhere in a message'stextfield, including inside inline code or a code block, even when the message shows no mention. The adapter now reportsisMention: falsefor these messages, so they no longer reachonNewMention.When an
app_mentiondoesn't reference the bot's known user ID, the adapter treats it as a mention only if the rendered message shows a mention of some user outside code. This covers theW…IDs that Enterprise Grid workspaces can use for the bot. The same rule now applies when the bot user ID hasn't been resolved yet, where the adapter previously treated everyapp_mentionas a mention.For messages whose blocks are Block Kit rather than
rich_text, such as a header or section posted by an integration, the adapter now reads a bot token intextoutside code as a mention when the blocks don't show the bot. This applies to bothapp_mentionandmessageevents, so the two events for the same message are classified the same way.48bb905: Read the body of a Block Kit message from its blocks. When a message carries blocks, Slack renders them and uses
textonly as the notification fallback, somessage.textandmessage.formattedcould miss content an app or workflow placed in the blocks, including the request in a mention that reachedonNewMention. When every block is asection,header,context,image,divider,actions, or table block, the text in those blocks now forms the body in block order, with tables in place and links frommrkdwntext inmessage.links. Messages with any other block type, including therich_textblocks a Slack client sends, keep usingtext, so content the adapter can't render still reaches the message.
4.42.0
14 Oct 20267b7d73c: Add a
visibleTooption toButtonandLinkButtonthat lists the user IDs allowed to see the button. The Slack adapter renders it asvisible_to_user_ids. Other adapters ignore it and show the button to everyone. It only hides the button, so action handlers still need to check who clicked.c70379b: Return every message ID from
SlackAdapter.stream(). When a long reply rotates into several messages, the result now includesmessageIds, which lists the messages of the reply in order. Its last entry isid. The newSlackStreamResulttype describes the result.f923b1c: Add a
blocksoption touploadSlackFilesso the message that shares the uploaded files can carry Block Kit blocks. Slack renders the files below the blocks. Passing bothblocksandinitialCommentthrows aTypeError, since Slack would silently ignoreblocks.
Minor Changes
7b7d73c: Add a
visibleTooption toButtonandLinkButtonthat lists the user IDs allowed to see the button. The Slack adapter renders it asvisible_to_user_ids. Other adapters ignore it and show the button to everyone. It only hides the button, so action handlers still need to check who clicked.c70379b: Return every message ID from
SlackAdapter.stream(). When a long reply rotates into several messages, the result now includesmessageIds, which lists the messages of the reply in order. Its last entry isid. The newSlackStreamResulttype describes the result.f923b1c: Add a
blocksoption touploadSlackFilesso the message that shares the uploaded files can carry Block Kit blocks. Slack renders the files below the blocks. Passing bothblocksandinitialCommentthrows aTypeError, since Slack would silently ignoreblocks.9a83b22: Isolate Slack message concurrency and turn cancellation by installation to prevent cross-workspace bot token reuse. Adapters can now namespace dedupe, lock, queue, and turn keys with the optional
Adapter.getConcurrencyScope()hook. In multi-workspace mode, messages queued under the old keys aren't migrated, and old and new workers don't exclude each other, so upgradechatand@chat-adapter/slacktogether and restart all workers.
Patch Changes
c70379b: Complete open task cards when a native Slack stream segment rotates, then replay the in-progress cards in the next segment. Retired segments now finish without Slack's error indicator. If Slack rejects the closing task cards, the adapter finalizes the segment without them and streams the rest of the reply as text only.
b37a550: Preserve literal text and code formatting in incoming Slack messages and correctly parse email and phone links
ec6edb8: Fix backward thread history reads returning older replies when a Slack thread spans multiple API pages. Backward reads now follow every
conversations.repliespage before selecting the newest messages, so long threads take one API call per page.c70379b: Cut Slack card text that goes past Block Kit's length limits, so a long value no longer makes Slack reject the message. This covers headers, section and muted text, subtitles, fields, link labels, button labels, image alt text, and select and radio options and placeholders. Cuts in mrkdwn text don't split a mention, link, or HTML entity, close a code fence left open, and keep the closing
*of bold text.
4.41.1
28 Sep 202644423bd: Convert Slack special mentions (
<!here>,<!channel>,<!everyone>) and user group mentions (<!subteam^ID|@handle>) to readable text in inbound messages.
Patch Changes
44423bd: Convert Slack special mentions (
<!here>,<!channel>,<!everyone>) and user group mentions (<!subteam^ID|@handle>) to readable text in inbound messages.
4.41.0
18 Sep 2026ad90432: Add opt-in selection change events for Select and RadioSelect inputs in Slack modals
6adca36: Support Slack egress proxies across Socket Mode, response URLs, webhook forwarding, and guarded file downloads with adapter-scoped transport options.
683eadc: Read the bot's mention from the message content instead of trusting the
app_mentionevent type.Slack can deliver
app_mentionfor a message whose bot-id reference only appears inside code, where it renders literally and is not an invocation. The adapter now classifies the content the way Slack renders it: auserelement for the bot, or a<@U…>token in mrkdwn content, is a mention. Inline code (style.code), preformatted elements, rich-texttextelements, link labels, andraw_texttable cells render literally and are not mentions.When a message carries blocks, they model its body and the flattened
textfield is not consulted, because it loses the code/literal distinction. A message whose content was inspected and holds no mention reportsisMention: false, even when the bot's display name appears as plain text. The synchronousparseMessagepath classifies the same way, so the pre-edit snapshot of an edited message agrees with the edited message.An
app_mentionevent whose content never shows the known bot id is still trusted, because Slack saw a mention under an id the adapter does not know (for example theW…id an Enterprise Grid workspace emits). When the adapter cannot identify the bot at all (botUserIdunresolved),app_mentionis trusted the same way and other messages stay undetermined.raw_texttable cells now render literally, matching how they are classified: Slack reserves mentions and links forrich_textcells, so a<@U…>token in araw_textcell no longer resolves to a display name.
Minor Changes
ad90432: Add opt-in selection change events for Select and RadioSelect inputs in Slack modals
6adca36: Support Slack egress proxies across Socket Mode, response URLs, webhook forwarding, and guarded file downloads with adapter-scoped transport options.
Patch Changes
683eadc: Read the bot's mention from the message content instead of trusting the
app_mentionevent type.Slack can deliver
app_mentionfor a message whose bot-id reference only appears inside code, where it renders literally and is not an invocation. The adapter now classifies the content the way Slack renders it: auserelement for the bot, or a<@U…>token in mrkdwn content, is a mention. Inline code (style.code), preformatted elements, rich-texttextelements, link labels, andraw_texttable cells render literally and are not mentions.When a message carries blocks, they model its body and the flattened
textfield is not consulted, because it loses the code/literal distinction. A message whose content was inspected and holds no mention reportsisMention: false, even when the bot's display name appears as plain text. The synchronousparseMessagepath classifies the same way, so the pre-edit snapshot of an edited message agrees with the edited message.An
app_mentionevent whose content never shows the known bot id is still trusted, because Slack saw a mention under an id the adapter does not know (for example theW…id an Enterprise Grid workspace emits). When the adapter cannot identify the bot at all (botUserIdunresolved),app_mentionis trusted the same way and other messages stay undetermined.raw_texttable cells now render literally, matching how they are classified: Slack reserves mentions and links forrich_textcells, so a<@U…>token in araw_textcell no longer resolves to a display name.c21ccbc: Add an opt-in webhook option to propagate message, action, and slash command handler errors through
waitUntilwhile preserving default behavior.
4.40.0
5 Sep 202651322dd: Decode the bot's own mention in incoming Slack messages. The adapter now resolves
<@U_BOT>to the bot's display name (@<DisplayName>) the same way it resolves every other user mention, instead of leaving the raw user-ID markup in place, and setsisMentionon the parsed message by detecting the bot's ID in the raw event text. This keepsmessage.textself-describing for downstream consumers (LLM prompts, classifiers) while preserving mention detection, which previously depended on the raw ID markup surviving in the text.d4a1f03: Rotate long-running native Slack streams before Slack expires them. Once a stream segment passes
streamSegmentMaxAgeMs(default four minutes) the adapter finalizes it at the next paragraph break and continues the reply in a new message, closing and reopening code fences, repeating table headers, replaying open task cards and the plan title, and keeping the agent session inprocessing. A segment Slack already expired during an idle gap is recovered the same way instead of failing the reply.2cc8cc3: Surface custom status text in the Agent messaging experience.
startTypingandsetAssistantStatuswith a custom status now call the legacyassistant.threads.setStatusendpoint, whose compatibility bridge renders the text in the agent-session loading UX — instead of silently dropping the text and showing the generic "Working…" indicator. Clearing (empty status) still transitions the session toactivevia the Agent Sessions lifecycle.
Minor Changes
51322dd: Decode the bot's own mention in incoming Slack messages. The adapter now resolves
<@U_BOT>to the bot's display name (@<DisplayName>) the same way it resolves every other user mention, instead of leaving the raw user-ID markup in place, and setsisMentionon the parsed message by detecting the bot's ID in the raw event text. This keepsmessage.textself-describing for downstream consumers (LLM prompts, classifiers) while preserving mention detection, which previously depended on the raw ID markup surviving in the text.d4a1f03: Rotate long-running native Slack streams before Slack expires them. Once a stream segment passes
streamSegmentMaxAgeMs(default four minutes) the adapter finalizes it at the next paragraph break and continues the reply in a new message, closing and reopening code fences, repeating table headers, replaying open task cards and the plan title, and keeping the agent session inprocessing. A segment Slack already expired during an idle gap is recovered the same way instead of failing the reply.2cc8cc3: Surface custom status text in the Agent messaging experience.
startTypingandsetAssistantStatuswith a custom status now call the legacyassistant.threads.setStatusendpoint, whose compatibility bridge renders the text in the agent-session loading UX — instead of silently dropping the text and showing the generic "Working…" indicator. Clearing (empty status) still transitions the session toactivevia the Agent Sessions lifecycle.
Patch Changes
78021c0: pass workspace context to suggested prompt resolvers in Agent view
8b6d7f3: Reactivate Slack Agent Sessions when
startTypingreceives an empty status.c2b6bff: Use the Slack bot user ID for bot-authored messages when a bot profile is available.
f485255: Harden webhook tenant isolation, require explicit Google Chat bot identity for reliable mention handling, use native Google Chat pagination, isolate Slack caches, and bound recording storage.
8fdaf4a: Stream post-and-edit fallback updates through Slack's
markdown_textfield instead oftext, so live-updating messages render markdown while the stream is in progress (and get the 12,000-character ceiling rather than 4,000)7609d8f: Validate external request targets before sending credentials, message content, or attachment requests.
4.39.0
28 Aug 20262ce2be0: Add Slack Agent Sessions lifecycle support, native stop cancellation through
thread.signal, automatic session titles, and session stop/title-change events while preserving the legacyassistant_viewcompatibility path.864d922: Keep alert attachment content on normalized Slack messages. Attachments that aren't link unfurls now contribute their pretext, title (linked to
title_linkwhen present, with the URL also surfaced inmessage.links), text, and fields instead of being dropped;fallbackfills in when nothing else on the attachment carries content. Matching how Slack renders these fields, they are treated as plain text unless listed in the attachment'smrkdwn_inarray, so literal*,_, and backticks in alert text survive normalization. Tables inside attachment blocks now stay adjacent to their attachment's text.Because attachment content is part of
message.text, mention detection andonMessagepattern handlers see it too: an attachment that quotes the bot's mention routes toonNewMention, and patterns match alert text. Handlers that should ignore other integrations' alerts can checkmessage.author.isBot.7c26965: prevent attachment downloads from sending credentials to untrusted hosts
Minor Changes
2ce2be0: Add Slack Agent Sessions lifecycle support, native stop cancellation through
thread.signal, automatic session titles, and session stop/title-change events while preserving the legacyassistant_viewcompatibility path.
Patch Changes
864d922: Keep alert attachment content on normalized Slack messages. Attachments that aren't link unfurls now contribute their pretext, title (linked to
title_linkwhen present, with the URL also surfaced inmessage.links), text, and fields instead of being dropped;fallbackfills in when nothing else on the attachment carries content. Matching how Slack renders these fields, they are treated as plain text unless listed in the attachment'smrkdwn_inarray, so literal*,_, and backticks in alert text survive normalization. Tables inside attachment blocks now stay adjacent to their attachment's text.Because attachment content is part of
message.text, mention detection andonMessagepattern handlers see it too: an attachment that quotes the bot's mention routes toonNewMention, and patterns match alert text. Handlers that should ignore other integrations' alerts can checkmessage.author.isBot.7c26965: prevent attachment downloads from sending credentials to untrusted hosts
e71bfea: Preserve the first line of incoming Slack code blocks when extracting message text and formatted content.
Only paired triple-backtick fences become code blocks: an unpaired fence, a fence inside inline code or a
<…>token, and a fence on a quoted line all stay literal text, matching how Slack renders them. Bold and strikethrough rewriting no longer touches fenced code content, and text following a closing fence can no longer turn into a blockquote, heading, or list.b6fa24c: guard attachment downloads across the remaining adapters
Slack, Discord, and WhatsApp attachment downloads now go through the shared guarded downloader: private and internal addresses are refused (as URL literals, through DNS resolution, and after redirects), responses are capped at 25 MB, and downloads time out after 30 seconds. Slack sends the bot token only on hops to trusted Slack origins, and WhatsApp keeps its access token on Meta's media hosts and the configured Graph origin. Telegram enforces the same size cap and timeout with the Web Fetch API so downloads keep working in runtimes like Cloudflare Workers.
downloadAttachmentin@chat-adapter/sharednow resolvesheadersper hop (pass a function to control what each redirect target receives), forwards the resolved headers to custom transports, and accepts anonResponsehook to reject unexpected final responses before the body is read.
4.38.1
17 Aug 2026764e475: preserve pasted Slack tables in parsed message content:
tableanddata_tableblocks become structured table nodes inmessage.formattedand tab-separated text inmessage.text. Table cells render mentions, channels, and links through the same mrkdwn converter as body text, unfurl and app attachments are excluded, date cells without a fallback are formatted from their timestamp, and tables pasted above the message text stay above it. Headerless pasted tables get an empty header row so GFM re-serialization doesn't promote the first data row to a header.SlackEvent.blocksis now typed with the exportedSlackMessageBlockinterface.
Patch Changes
764e475: preserve pasted Slack tables in parsed message content:
tableanddata_tableblocks become structured table nodes inmessage.formattedand tab-separated text inmessage.text. Table cells render mentions, channels, and links through the same mrkdwn converter as body text, unfurl and app attachments are excluded, date cells without a fallback are formatted from their timestamp, and tables pasted above the message text stay above it. Headerless pasted tables get an empty header row so GFM re-serialization doesn't promote the first data row to a header.SlackEvent.blocksis now typed with the exportedSlackMessageBlockinterface.
4.38.0
14 Aug 2026Only updates dependencies:chat 4.38.0@chat-adapter/shared 4.38.0
4.37.0
7 Aug 20264ac0455: Add message update and delete lifecycle callbacks, with Slack message_changed and message_deleted dispatch support.
4cc3445: Bound the length of bracketed URLs parsed from message text in the link-unfurl fallback, avoiding a quadratic scan on adversarial input. Valid links are unaffected.
Minor Changes
4ac0455: Add message update and delete lifecycle callbacks, with Slack message_changed and message_deleted dispatch support.
Patch Changes
6f0d2f0: Resolve outgoing @name mentions on the Slack native streaming path so streamed responses mention users consistently with the post-and-edit fallback. Committed renderer text is resolved incrementally, keeping fenced code literal and preserving the existing ambiguity semantics.
4cc3445: Bound the length of bracketed URLs parsed from message text in the link-unfurl fallback, avoiding a quadratic scan on adversarial input. Valid links are unaffected.
c311827: Preserve the Slack channel ID when converting labeled channel tokens (
<#C123|general>now becomes#general (C123)) so agents can pass the ID to channel tools, and normalize the commonly hallucinated<label|url>link order before Markdown conversion
4.36.0
1 Aug 20260153a39: Add
DateInputandNumberInputmodal children. The Slack adapter renders them as adatepickerand anumber_input, the Teams adapter asInput.DateandInput.Number, and both submitted values arrive inevent.valuesas strings.Teams submit values that arrive as JSON numbers are now stringified into
event.valuesinstead of being dropped. This fixesInput.Number, but applies to any numeric value a Teams dialog submits — a key that was previously absent fromevent.valueswill now be present as a string.
Minor Changes
0153a39: Add
DateInputandNumberInputmodal children. The Slack adapter renders them as adatepickerand anumber_input, the Teams adapter asInput.DateandInput.Number, and both submitted values arrive inevent.valuesas strings.Teams submit values that arrive as JSON numbers are now stringified into
event.valuesinstead of being dropped. This fixesInput.Number, but applies to any numeric value a Teams dialog submits — a key that was previously absent fromevent.valueswill now be present as a string.
4.35.0
24 Jul 2026bb7cd12: Expose sender email addresses on normalized incoming Slack message authors.
message.author.emailis populated from the same cachedusers.infolookup used for display names and requires theusers:read.emailscope; without it the field stays undefined.907450d: Enterprise Grid fixes:
80def3a: Add optional
isSystemfield to the normalized messageAuthortype to distinguish platform-generated messages from humans and bots. The Slack adapter now setsisSystem: truefor messages authored by Slack's reservedUSLACKuser (e.g. "@user archived the channel" notifications in DMs), so consumers no longer need to hard-code Slack-specific user IDs.
Minor Changes
bb7cd12: Expose sender email addresses on normalized incoming Slack message authors.
message.author.emailis populated from the same cachedusers.infolookup used for display names and requires theusers:read.emailscope; without it the field stays undefined.907450d: Enterprise Grid fixes:
handleOAuthCallbacknow handles org-wide installs (is_enterprise_install): Slack returnsteam: nullfor these, and the installation is now keyed by the enterprise ID — the same key webhook token resolution looks up — instead of failing. The result includesenterpriseIdandisEnterpriseInstall, andSlackInstallationrecords both.Socket mode now resolves per-installation tokens for events, slash commands, and interactive payloads in multi-workspace deployments (matching the HTTP webhook path), and no longer drops
enterprise_id/is_enterprise_install/is_ext_shared_channelfrom event payloads.The user profile cache and display-name mention reverse index are now scoped by installation in multi-workspace deployments, so profiles fetched with one workspace's token no longer bleed into another and mentions can no longer resolve to a same-named user from a different workspace. Existing cache entries repopulate on first lookup (single-workspace keys are unchanged).
withBotTokenaccepts an optional{ installationId }so proactive/cron posts outside webhook handling scope these caches too.API calls made while handling an event from an org-wide install now pass the event's
team_idexplicitly, as Slack requires for workspace-scoped methods (conversations.list,usergroups.*, …) on org tokens. When an event carries acontext_team_id(shared channels hosted on an "away" workspace), channel-addressed calls echo it back asclient_context_team_id.Retried event deliveries (
x-slack-retry-num, socketretry_num) are dropped when the original delivery was already dispatched, using anevent_idmarker in the state adapter (24-hour TTL). Events whose first delivery never arrived are still recovered via the retry.Bare
@W…mentions in outgoing messages are now recognized as raw Enterprise Grid user IDs (previously only@U…was), so they render as real mentions instead of being treated as display names.Event token resolution now prefers the envelope's
authorizations[0]— Slack's documented location for the event's installation identity — over the top-levelteam_id/enterprise_id, which can name a different workspace for Slack Connect shared-channel events. Top-level fields remain as a fallback.
Patch Changes
80def3a: Add optional
isSystemfield to the normalized messageAuthortype to distinguish platform-generated messages from humans and bots. The Slack adapter now setsisSystem: truefor messages authored by Slack's reservedUSLACKuser (e.g. "@user archived the channel" notifications in DMs), so consumers no longer need to hard-code Slack-specific user IDs.92530dd: Return a replyable Slack thread ID from
channel.post()by using the posted top-level message's timestamp as the thread root.
4.34.0
13 Jul 2026Reading the note…
4.33.0
7 Jul 2026Reading the note…
4.32.0
1 Jul 2026Reading the note…
4.31.0
16 Jun 2026Reading the note…
4.30.0
2 Jun 2026Reading the note…
4.29.0
18 May 2026Reading the note…
4.28.1
8 May 2026Reading the note…
4.27.0
30 Apr 2026Reading the note…
4.26.0
14 Apr 2026Reading the note…
4.25.0
11 Apr 2026Reading the note…
4.24.0
7 Apr 2026Reading the note…
4.23.0
26 Mar 2026Reading the note…
4.22.0
24 Mar 2026Reading the note…
4.21.0
23 Mar 2026Reading the note…
4.20.2
16 Mar 2026Reading the note…
4.20.1
12 Mar 2026Reading the note…
4.20.0
11 Mar 2026Reading the note…
4.19.0
10 Mar 2026Reading the note…
4.18.0
7 Mar 2026Reading the note…
4.17.0
6 Mar 2026Reading the note…
4.16.1
4 Mar 2026Reading the note…
4.16.0
4 Mar 2026Reading the note…
4.15.0
26 Feb 2026Reading the note…
4.14.0
24 Feb 2026Reading the note…
4.13.4
24 Feb 2026Reading the note…
4.13.3
23 Feb 2026Reading the note…
4.13.2
23 Feb 2026Reading the note…
4.13.1
20 Feb 2026Reading the note…
4.13.0
20 Feb 2026Reading the note…
4.12.0
18 Feb 2026Reading the note…
4.11.0
16 Feb 2026Reading the note…
4.10.1
15 Feb 2026Reading the note…
4.10.0
15 Feb 2026Reading the note…
4.9.1
12 Feb 2026Reading the note…
4.9.0
10 Feb 2026Reading the note…
4.8.0
6 Feb 2026Reading the note…
4.7.2
6 Feb 2026Reading the note…
4.7.1
24 Jan 2026Reading the note…
4.7.0
23 Jan 2026Reading the note…