The Slack node posts to Slack and can wait for a person's answer there. With a Slack Webhook credential it sends one message to the webhook's channel. With a Slack Bot credential (a bot token, xoxb-…) it runs every operation below: channel messages, direct messages, thread replies, message updates, outcome cards, reactions, reading messages, downloading and sending files, and approvals, buttons and forms that pause the run until someone answers.
Overview
| Property | Value |
|---|---|
| Inputs | 1 |
| Outputs | 1 |
| Output | Where the message landed (channel, ts, threadTs), or the answer for approvals, buttons and forms |
Operations (Slack Bot credential)
| Operation | What it does | Waits |
|---|---|---|
| Send channel message | Posts to a channel, or to a person's DMs when given their id or email | No |
| Send DM | Opens a direct message with a person (user id or email) and posts there | No |
| Reply in thread | Replies under a message; optionally also shows the reply in the channel | No |
| Update message | Replaces the text of a message an earlier step posted | No |
| Post final outcome | Posts a colored outcome card (success, failure, warning, info) | No |
| Request approval | Posts Approve, Request changes and Reject buttons | Yes |
| Send message with buttons | Posts up to five buttons; the one pressed continues the run | Yes |
| Send form | Posts a button that opens a Slack form with up to ten fields | Yes |
| Add reaction | Adds an emoji reaction to a message | No |
| Delete message | Deletes a message the bot posted | No |
| Read messages | Reads a channel's latest messages, or a thread's replies | No |
| Find person | Looks a person up by id or email | No |
| Download files | Saves a message's files to Heym Drive and returns them with the message's text | No |
| Send files | Shares Heym Drive files in a channel, a DM or a thread, with an optional message | No |
Parameters
| Parameter | Type | Description |
|---|---|---|
credentialId | UUID | A Slack Webhook or Slack Bot credential from Credentials |
slackOperation | string | One of the operations above (Slack Bot only, default sendMessage) |
slackChannel | expression | #name, a channel id (C…), or a person (user id U… or email) to post in their DMs |
slackUser | expression | The person for Send DM and Find person |
message | expression | Message text in Slack formatting. Supports expressions. |
slackThreadTs | expression | The thread to post in, such as $announce.threadTs |
slackMessageTs | expression | The message to update, react to or delete, such as $announce.ts |
slackButtons | list | Up to five {label, value, style} buttons |
slackFormTitle, slackSubmitLabel, slackFormFields | text, list | The form's title, submit button and fields (text, multiline, number, email, date, select) |
slackAllowedUsers | expression | Who may answer an approval, buttons or a form: user ids or emails, comma separated. Empty lets anyone in the channel answer. |
slackOutcomeStatus, slackOutcomeTitle | text | The outcome card's color and headline. The status can follow an approval: $approval.approval. |
slackFile | expression | Download files: a Slack message such as $slackEvent.event (all its files and its text), a message or file link, a file id (F…), or a list of files |
slackUploadFile | expression | Send files: the run's Heym Drive files, such as $files.file_ids or $drive.id |
Output
Posting operations output channel, ts, threadTs and text, so a later Slack step can reply in the same thread or update the message.
Read messages outputs transcript: the messages oldest first, one [time] name: text per line, ready for an LLM to summarize. It also outputs the raw messages list and count.
Download files saves up to ten files to Heym Drive and outputs files (each with id, slack_file_id, filename, mime_type, size_bytes and download_url), file_ids, count, and the message's text, channel, ts and user. The first file's fields are also at the top, so $files.filename works for a single file. Give $files.file_ids to an Agent in its user message and it reads the files with file analysis. A file Slack only links to (for example a Google Drive link) or a file larger than the Drive limit stops the step with a message.
Send files shares up to ten Drive files in one Slack message and outputs channel, threadTs, files and count. It sends only the run's own files: the output of Download files, a Drive node's Get (for example $drive.id), a Converter or a Code node, or a file uploaded through the File Upload trigger. A Drive id typed straight into Files is refused, so other Drive files are posted only through a visible Drive step.
Messages are posted in Slack's own formatting. Markdown that a model writes, such as **bold**, ## Heading, [text](url) or - item, is converted before posting, so an LLM's answer can go into a message as it is.
Approvals, buttons and forms pause the run. The same request appears in the Heym inbox and in Heym Work's Activity, so it can be decided there as well as in Slack. When it is answered, the step outputs the posting fields plus:
| Field | Description |
|---|---|
answeredBy.id, answeredBy.name | The Slack person who answered (empty when decided in Heym) |
answeredIn | slack or heym |
approval | approved, changes_requested or rejected (approvals) |
comment | What the reviewer asked to change (approvals) |
choice.label, choice.value | The button pressed (buttons) |
values.<field> | Each form field by its output key (forms) |
Branch on the answer with a Condition or Switch node, for example $approval.approval == "approved".
Setup
Slack Webhook: create an Incoming Webhook in your Slack workspace and add it as a Slack Webhook credential.
Slack Bot:
- In the credential dialog, choose Slack Bot (Token) and select Copy app manifest.
- At api.slack.com/apps, create an app from a manifest and paste it. The manifest asks for every scope the operations need.
- Install the app to your workspace, then paste the Bot User OAuth Token and the Signing Secret into the credential and save it. Copy the manifest again after saving: it then also carries the credential's interactivity and events URLs.
- Open the credential again and copy its Interactivity Request URL into the Slack app under Interactivity & Shortcuts. Approvals, buttons and forms send their answers there.
- For a Slack Trigger, copy the credential's Event Subscriptions Request URL too. Every Slack Trigger on the credential hears messages, DMs and mentions through it.
- Invite the bot to private channels it should post in (
/invite @Heym).
Download files needs the files:read scope and Send files needs files:write. The manifest includes both; an app created from an older manifest must add them and be reinstalled to the workspace.
The same Slack Bot credential also verifies Slack Trigger events. A flow that listens with it ignores the bot's own posts, uploads and edits, so replying in the channel it listens to does not start it again.
Example: approval with an outcome in the same thread
{"type": "slack", "data": {"label": "approval", "credentialId": "slack-credential-uuid", "slackOperation": "requestApproval", "slackChannel": "#finance-approvals", "message": "Refund of $userInput.body.amount for $userInput.body.customer"}}{"type": "slack", "data": {"label": "outcome", "credentialId": "slack-credential-uuid", "slackOperation": "postOutcome", "slackChannel": "$approval.channel", "slackThreadTs": "$approval.threadTs", "slackOutcomeStatus": "$approval.approval", "slackOutcomeTitle": "Refund $approval.approval", "message": "Decided by $approval.answeredBy.name"}}Use with Error Handler for failure notifications:
"message": "Error in $errorHandler.errorNode: $errorHandler.error"Egress Safety
- The webhook URL stored in a Slack Webhook credential must use
http://orhttps://and resolve only to public addresses. Loopback, private, link-local, multicast, and cloud-metadata destinations are blocked. - Heym validates the resolved addresses and pins the connection target before sending, so a DNS answer cannot move the request onto an internal address after the check. Environment proxies are disabled while the guard is active, and redirects are not followed.
- Deployments that post to an internal webhook receiver can set
HEYM_HTTP_ALLOW_PRIVATE_URLS=trueon a trusted self-hosted instance. Keep the default on hosted or multi-tenant deployments. - Slack Bot calls go only to
https://slack.com/api. Answers from Slack are accepted only with a valid signature from the credential's signing secret.
Upgrade note for v0.0.109: this check is new for Slack. A credential whose webhook URL points at loopback or a private address is refused unless the setting above is enabled.
Related
- Node Types – Overview of all node types
- Slack Trigger – Start a workflow from a Slack message
- Human-in-the-Loop – Reviews and the inbox
- Error Handler – Send Slack on workflow failure
- Credentials Tab – Add Slack credentials