Slack
Connect Slack at the Trodo team level to post messages, manage channels the bot can access, and trigger Agents from Slack events.
Slack is connected once per Trodo team, not per Agent, channel, or person. The team bot token is what Agents use.
Slack connection
Slack is connected at the Trodo team / workspace level under Settings → Integrations → Slack.
That install stores:
- a bot token (
xoxb) for almost every Agent action and trigger - an optional user token from the person who clicked Connect, used only for search and updating that installer's own Slack profile
There is no per-Agent Slack login, no per-channel OAuth, and no personal Slack identity for the workflow author.
Open Settings → Integrations and choose Slack.
Authorize the Trodo app in your Slack workspace. Slack asks the installer to approve bot scopes and optional user scopes.
Invite @Trodo to any private channel the Agent must use. Public channels the bot is not in may allow posting (chat:write.public) but not history, reactions, or most other operations.
If App Mention triggers fail with a missing-permission error, reconnect Slack. Adding app_mentions:read to Trodo's requested scopes does not update existing installations. Reconnect and approve the new permission.
Channel access
Treat these as two different facts:
| Concept | Meaning |
|---|---|
| Slack workspace connected | The Trodo team has a bot token for that Slack workspace. |
| Channel or DM in the picker | The Trodo bot can use that conversation for the current Agent step. |
The channel picker lists only usable conversations. Public channels the bot can post to (including via chat:write.public) appear for Send message even if the bot is not a member. History, reactions, and triggers still require the bot to be in the conversation, so those pickers omit public channels the bot has not joined.
Private channels the bot has not been invited to do not appear. After you invite the Trodo bot in Slack, click Refresh on the picker.
If an Agent was saved against a channel that is later archived, deleted, or from which the bot is removed, the run fails with a clear error. The picker does not treat a previously listed channel as permanently valid.
Private channels
Do not use Join channel to enter a private channel. Slack does not allow conversations.join on private channels.
Invite @Trodo to the private channel in Slack, then retry. The backend re-checks membership when the Agent runs.
Resource pickers
Workflow authors pick Slack resources by name. Trodo resolves Slack IDs, message timestamps, and pagination internally.
| Picker | Used for |
|---|---|
| Channel or DM | Conversations the Trodo bot can use for that action |
| Person | Workspace members (invite, kick, get user) |
| Message | Recent messages in the selected conversation (update, delete, permalink, threads, reactions) |
| File | Files the bot can see |
| User group | Paid-plan user groups |
| Reaction | Common Slack emoji |
Expressions such as {{ $trigger.ts }} still work for values that come from an upstream node. Do not paste raw Slack IDs, timestamps, or pagination cursors into the form.
List actions return name, useful metadata, and slack_id for downstream steps. IDs are not the primary thing the output shows.
User-token actions
These operations use the Slack user token associated with the team installation / installer, not the Trodo user who is editing the Agent:
- Search messages
- Update user profile (installer identity only: Trodo does not send Slack's admin
userparameter)
If those nodes fail, reconnect Slack at Settings → Integrations and approve the user permissions on the consent screen.
Update user profile can set status, display name, title, and phone for the Slack account that connected the integration. It cannot target another workspace member from Trodo, even if the installer is a Slack admin.
Triggers
A trigger starts an Agent when Slack delivers an event to:
POST /api/integrations/slack/events
Trodo verifies the Slack signing secret, rejects stale timestamps, ACKs within 3 seconds, then dispatches in the background.
| Trigger | Slack event | Bot scope | Slack app Event Subscription | Filters | Notes |
|---|---|---|---|---|---|
| On any event | whatever Slack posts | (varies) | whichever events you subscribe | channel or DM | Fires only for the selected conversation. Workspace-wide events (team_join, channel_created) have no conversation picker. |
| On bot app mention | app_mention | app_mentions:read | app_mention | channel or DM | Existing installs must reconnect. Trodo bot self-mentions are ignored. |
| On file shared | file_shared | files:read | file_shared | channel or DM | Matches event.channel_id. |
| On new message in channel | message | channels:history / groups:history / im:history / mpim:history | message.channels, message.groups, message.im, message.mpim as needed | channel or DM | Matches Slack channel ID, never the name. Messages from Trodo's own bot do not fire. |
| On new public channel created | channel_created | channels:read | channel_created | none | Public channels only. No conversation picker. |
| On new user | team_join | users:read | team_join | none | Workspace-level. No conversation picker. |
| On reaction added | reaction_added | reactions:read | reaction_added | channel or DM + optional reaction name | Both filters are enforced. |
Subscribe at least the events you actually use. Duplicate Slack deliveries (event_id) start an Agent at most once per trigger.
Actions
Every action still depends on Slack scopes, channel membership, channel type, and Slack API rules. A connected workspace is not a guarantee.
| Area | Implemented | Limits |
|---|---|---|
| Messages | Send, update, delete, permalink, search | Update/delete only succeed for messages the Trodo bot posted. Trodo checks authorship before calling Slack. Search uses the installer user token. Scheduling and ephemeral messages are not implemented. |
| Channels | Create, archive/unarchive, get, list, history, thread replies, invite, kick, join, leave, members, rename, topic, purpose | Join works for public channels only. History/replies/reactions require membership even when chat:write.public allows posting. Archive/rename/topic/purpose are not valid for DMs. List defaults to public, private, IM, and MPIM conversations the bot can see. List members returns names and emails. |
| Files | Upload text, get, list | Upload uses Slack's external upload flow (files.getUploadURLExternal + files.completeUploadExternal). Content is UTF-8 text only (not a binary file picker). Sharing to a private channel requires membership. |
| Reactions | Add, remove, get | Bot membership required. Pick a message and an emoji; do not type timestamps or :thumbsup: colons. |
| Users | Get, list, profile, status, update profile | Profile update uses the installer user token and only that Slack identity. List users returns names and emails. |
| User groups | Create, enable, disable, list, update | Slack returns paid_teams_only on free workspaces: that is a Slack plan limit, not a Trodo bug. |
Stars (add / remove / list) are not available. Slack replaced Stars with Later; those APIs no longer match what users see.
Public vs private vs DM
- Public: posting can work without membership if
chat:write.publicwas granted; history, reactions, and most other operations still need the bot in the channel. - Private: the bot must be a member. Invite @Trodo; do not join from Trodo.
- DM / MPIM: history/replies/send are supported when the bot is a participant. Channel archive/rename/invite/join are not.
Use it
- Post to a channel the bot can access when an alert trigger fires.
- Reply to an app mention with an AI agent answer (reconnect Slack if
app_mentions:readis missing). - Open a thread and update bot-authored messages as a long-running workflow progresses.