# Slack (Bot) on boxd

> Slackbot gives agents workspace-wide read access to a Slack workspace on behalf of the installing user - search messages and files, browse channel and thread history, and look up users and channels - while continuing to post and react as the bot. Includes direct messages and user email addresses so agents can search across DMs and resolve users by email.

- Page: https://boxd.sh/integrations/slackbot/
- CLI: `run slackbot` (100 commands, 33 marked common)
- SDK: `import { slackbot } from "@boxd/run"`; every parameter and response type is at `@boxd/run/slackbot`
- Triggers: 9
- Connect: `run auth slackbot` (Sign in with Slack), or https://app.boxd.sh/integrations/detail/slackbot
- All integrations: https://boxd.sh/integrations/ (Markdown: https://boxd.sh/integrations/index.md)

## From the shell

```sh
run auth slackbot      # once: prints a link to connect your account
run slackbot           # list its commands
run slackbot find-users
```

Parameters are flags (`--flag value`); object and array parameters take a JSON string. Output is YAML, or JSON with `--json`. Calls use your own connection; `--scope <name>` uses a connection shared with your team.

## From a script

```ts
import { slackbot } from "@boxd/run";

const result = await slackbot.findUsers({});
console.log(result);

slackbot.on("channel-created", async (event) => {
  // New Channel Created Trigger: runs on this machine, once per event
  console.log(event);
});
```

Run it with `run slackbot.run.ts`. A script that calls `.on()` keeps running as a job and handles each event.

## Commands

Required flags are listed; `run slackbot <command> --help` lists the optional ones. "common" marks what `run slackbot` shows without `--all`.

| Command | SDK method | Required flags | Optional | Description |
|---|---|---|---|---|
| `add-call-participants` | `slackbot.addCallParticipants()` | `--id` `--users` | 0 | Registers new participants added to a Slack call |
| `add-reaction-to-item` ·common | `slackbot.addReactionToItem()` | `--channel` `--name` `--timestamp` | 0 | Adds a specified emoji reaction to an existing message in a Slack channel, identified by its timestamp; does not remove or retrieve reactions |
| `add-remote-file` | `slackbot.addRemoteFile()` | `--external-id` `--external-url` `--title` | 3 | Adds a reference to an external file (e.g., Google Drive, Dropbox) to Slack for discovery and sharing, requiring a unique `external_id` and an `external_url` accessible by Slack |
| `archive-conversation` | `slackbot.archiveConversation()` | — | 1 | Archives a Slack conversation by its ID, rendering it read-only and hidden while retaining history, ideal for cleaning up inactive channels; be aware that some channels (like #general or certain DMs)… |
| `close-dm` | `slackbot.closeDm()` | `--channel` | 0 | Closes a Slack direct message (DM) or multi-person direct message (MPDM) channel, removing it from the user's sidebar without deleting history; this action affects only the calling user's view |
| `create-canvas` ·common | `slackbot.createCanvas()` | — | 3 | Creates a new Slack Canvas with the specified title and optional content |
| `create-channel` | `slackbot.createChannel()` | `--name` | 2 | Initiates a public or private channel-based conversation in a Slack workspace |
| `create-list` ·common | `slackbot.createList()` | `--name` | 5 | Creates a new Slack List via `slackLists.create` |
| `create-list-item` ·common | `slackbot.createListItem()` | `--list-id` | 3 | Creates a new item (row) in a Slack List via `slackLists.items.create` |
| `create-reminder` ·common | `slackbot.createReminder()` | `--text` `--time` | 2 | Creates a Slack reminder with specified text and time; time accepts Unix timestamps, seconds from now, or natural language (e.g., 'in 15 minutes', 'every Thursday at 2pm') |
| `create-user-group` | `slackbot.createUserGroup()` | `--name` | 7 | Creates a new User Group (often referred to as a subteam) in a Slack workspace |
| `customize-url-unfurl` | `slackbot.customizeUrlUnfurl()` | — | 10 | Customizes URL previews (unfurling) in a specific Slack message using a URL-encoded JSON in `unfurls` to define custom content or remove existing previews |
| `delete-canvas` ·common | `slackbot.deleteCanvas()` | `--canvas-id` | 0 | Deletes a Slack Canvas permanently and irreversibly |
| `delete-file` | `slackbot.deleteFile()` | `--file` | 0 | Permanently deletes an existing file from a Slack workspace using its unique file ID; this action is irreversible and also removes any associated comments or shares |
| `delete-file-comment` | `slackbot.deleteFileComment()` | `--file` `--id` | 0 | Deletes a specific comment from a file in Slack; this action is irreversible |
| `delete-list-access` ·common | `slackbot.deleteListAccess()` | `--list-id` | 2 | Revokes sharing access on a Slack List via `slackLists.access.delete` |
| `delete-list-item` ·common | `slackbot.deleteListItem()` | `--id` `--list-id` | 0 | Deletes an item (row) from a Slack List via `slackLists.items.delete` |
| `delete-multiple-list-items` ·common | `slackbot.deleteMultipleListItems()` | `--ids` `--list-id` | 0 | Deletes several items (rows) from a Slack List in one call via `slackLists.items.deleteMultiple` |
| `delete-reminder` | `slackbot.deleteReminder()` | `--reminder` | 1 | Deletes an existing Slack reminder, typically when it is no longer relevant or a task is completed; this operation is irreversible |
| `delete-scheduled-message` | `slackbot.deleteScheduledMessage()` | `--channel` `--scheduled-message-id` | 1 | Deletes a pending, unsent scheduled message from the specified Slack channel, identified by its `scheduled_message_id` |
| `deletes-message-from-chat` | `slackbot.deletesMessageFromChat()` | — | 3 | Deletes a message, identified by its channel ID and timestamp, from a Slack channel, private group, or direct message conversation; the authenticated user or bot must be the original poster |
| `disable-user-group` | `slackbot.disableUserGroup()` | `--usergroup` | 2 | Disables a specified, currently enabled Slack User Group by its unique ID, effectively archiving it by setting its 'date_delete' timestamp; the group is not permanently deleted and can be re-enabled |
| `download-file` ·common | `slackbot.downloadFile()` | `--file` | 4 | Download Slack file content and convert it to a publicly accessible URL |
| `edit-canvas` ·common | `slackbot.editCanvas()` | `--canvas-id` | 4 | Edits a Slack Canvas with granular control over content placement |
| `enable-public-sharing-of-file` | `slackbot.enablePublicSharingOfFile()` | `--file` | 0 | Enables public sharing for an existing Slack file by generating a publicly accessible URL; this action does not create new files |
| `enable-user-group` | `slackbot.enableUserGroup()` | `--usergroup` | 2 | Enables a disabled User Group in Slack using its ID, reactivating it for mentions and permissions; this action only changes the enabled status and cannot create new groups or modify other properties |
| `end-call` | `slackbot.endCall()` | `--id` | 1 | Ends an ongoing Slack call, identified by its ID (obtained from `calls.add`), optionally specifying the call's duration |
| `fetch-conversation-history` ·common | `slackbot.fetchConversationHistory()` | `--channel` | 6 | Fetches a chronological list of messages and events from a specified Slack conversation, accessible by the authenticated user/bot, with options for pagination and time range filtering |
| `fetch-item-reactions` | `slackbot.fetchItemReactions()` | — | 5 | Fetches reactions for a Slack message, file, or file comment |
| `fetch-message-thread-from-conversation` | `slackbot.fetchMessageThreadFromConversation()` | — | 8 | Retrieves replies to a specific parent message in a Slack conversation, using the channel ID and the parent message's timestamp (`ts`) |
| `fetch-team-info` | `slackbot.fetchTeamInfo()` | — | 2 | Fetches comprehensive metadata about the current Slack team, or a specified team if the provided ID is accessible |
| `find-channels` ·common | `slackbot.findChannels()` | `--query` | 6 | Find channels in a Slack workspace by any criteria - name, topic, purpose, or description |
| `find-user-by-email-address` | `slackbot.findUserByEmailAddress()` | `--email` | 0 | Retrieves the Slack user object for an active user by their registered email address; requires the users:read.email OAuth scope |
| `find-users` ·common | `slackbot.findUsers()` | — | 9 | Find users in a Slack workspace by any criteria - email, name, display name, or other text |
| `get-bot-user` | `slackbot.getBotUser()` | — | 2 | Fetches information for a specified, existing Slack bot user; will not work for regular user accounts or other integration types |
| `get-call-info` | `slackbot.getCallInfo()` | `--id` | 0 | Retrieves a point-in-time snapshot of a specific Slack call's information |
| `get-canvas` ·common ·deprecated | `slackbot.getCanvas()` | `--canvas-id` | 4 | Use SLACK_RETRIEVE_DETAILED_INFORMATION_ABOUT_FILE instead |
| `get-list-item` ·common | `slackbot.getListItem()` | `--id` `--list-id` | 1 | Fetches a single item (row) from a Slack List via `slackLists.items.info` |
| `get-reminder` | `slackbot.getReminder()` | `--reminder` | 1 | Retrieves detailed information for an existing Slack reminder specified by its ID; this is a read-only operation |
| `get-remote-file` | `slackbot.getRemoteFile()` | — | 2 | Retrieve information about a remote file added to Slack via the files.remote API |
| `get-team-profile` | `slackbot.getTeamProfile()` | — | 2 | Retrieves all profile field definitions for a Slack team, optionally filtered by visibility, to understand the team's profile structure |
| `get-unread-messages-from-user` ·common | `slackbot.getUnreadMessagesFromUser()` | `--user-id` | 1 | Retrieves unread direct messages from a specific user by opening their DM conversation, checking for unread messages, and fetching message history since the last read timestamp |
| `get-user-dnd-status` | `slackbot.getUserDndStatus()` | `--users` | 1 | Retrieves a user's current Do Not Disturb status |
| `get-user-presence` | `slackbot.getUserPresence()` | — | 1 | Retrieves a Slack user's current real-time presence (e.g., 'active', 'away') to determine their availability, noting this action does not provide historical data or status reasons |
| `invite-users-to-channel` | `slackbot.inviteUsersToChannel()` | — | 3 | Invites users to an existing Slack channel using their valid Slack User IDs |
| `join-existing-conversation` | `slackbot.joinExistingConversation()` | `--channel` | 0 | Joins an existing Slack conversation (public channel, private channel, or multi-person direct message) by its ID, if the authenticated user has permission |
| `leave-conversation` | `slackbot.leaveConversation()` | `--channel` | 0 | Leaves a Slack conversation given its channel ID; fails if leaving as the last member of a private channel or if used on a Slack Connect channel |
| `list-all-channels` ·common | `slackbot.listAllChannels()` | — | 5 | Lists conversations available to the user with various filters and search options |
| `list-all-users` ·common | `slackbot.listAllUsers()` | — | 4 | Retrieves a paginated list of all users with profile details, status, and team memberships in a Slack workspace; data may not be real-time |
| `list-available-workspaces` ·common | `slackbot.listAvailableWorkspaces()` | `--user` | 0 | List Slack workspaces where both the connection and target user have access |
| `list-canvases` ·common ·deprecated | `slackbot.listCanvases()` | — | 8 | Use SLACK_LIST_FILES_WITH_FILTERS_IN_SLACK instead (pass types="canvas" for equivalent behavior) |
| `list-conversations` | `slackbot.listConversations()` | — | 6 | List conversations (channels/DMs) accessible to a specified user (or the authenticated user if no user ID is provided), respecting shared membership for non-public channels |
| `list-custom-emojis` | `slackbot.listCustomEmojis()` | — | 1 | Retrieves all custom emojis for the Slack workspace (image URLs or aliases), not standard Unicode emojis; does not include usage statistics or creation dates |
| `list-files-with-filters-in-slack` | `slackbot.listFilesWithFiltersInSlack()` | — | 9 | Lists files and their metadata within a Slack workspace, filterable by user, channel, timestamp, or type; returns metadata only, not file content |
| `list-list-items` ·common | `slackbot.listListItems()` | `--list-id` | 3 | Lists the rows (items) in a Slack List via `slackLists.items.list` |
| `list-pinned-items` | `slackbot.listPinnedItems()` | `--channel` | 0 | Retrieves all messages and files pinned to a specified channel; the caller must have access to this channel |
| `list-reminders` | `slackbot.listReminders()` | — | 1 | Lists all reminders with their details for the authenticated Slack user; returns an empty array if no reminders exist (valid state, not an error) |
| `list-remote-files` | `slackbot.listRemoteFiles()` | — | 5 | Retrieve information about a team's remote files |
| `list-unread-channel-messages` ·common | `slackbot.listUnreadChannelMessages()` | `--channel` | 3 | Lists all unread messages in a specified Slack channel for the authenticated user |
| `list-user-group-members` | `slackbot.listUserGroupMembers()` | `--usergroup` | 2 | Retrieves a list of all user IDs within a specified Slack user group, with an option to include users from disabled groups |
| `list-user-groups` | `slackbot.listUserGroups()` | — | 4 | Lists user groups in a Slack workspace, including user-created and default groups; results for large workspaces may be paginated |
| `list-user-reactions` | `slackbot.listUserReactions()` | — | 7 | Lists all reactions added by a specific user to messages, files, or file comments in Slack, useful for engagement analysis when the item content itself is not required |
| `lookup-canvas-sections` ·common | `slackbot.lookupCanvasSections()` | `--canvas-id` `--criteria` | 0 | Looks up section IDs in a Slack Canvas for use with targeted edit operations |
| `open-dm` | `slackbot.openDm()` | — | 4 | Opens or resumes a Slack direct message (DM) or multi-person direct message (MPIM) by providing either user IDs or an existing channel ID |
| `pin-item` | `slackbot.pinItem()` | `--channel` `--timestamp` | 0 | Pins a message to a specified Slack channel; the message must not already be pinned |
| `remove-call-participants` | `slackbot.removeCallParticipants()` | `--id` `--users` | 0 | Registers participants removed from a Slack call |
| `remove-reaction-from-item` ·common | `slackbot.removeReactionFromItem()` | `--name` | 4 | Removes an emoji reaction from a message, file, or file comment in Slack |
| `remove-remote-file` | `slackbot.removeRemoteFile()` | — | 3 | Removes the Slack reference to an external file (which must have been previously added via the remote files API), specified by either its `external_id` or `file` ID (one of which is required)… |
| `remove-user-from-conversation` | `slackbot.removeUserFromConversation()` | — | 2 | Removes a specified user from a Slack conversation (channel); the caller must have permissions to remove users and cannot remove themselves using this action |
| `rename-conversation` | `slackbot.renameConversation()` | — | 2 | Renames a Slack channel, automatically adjusting the new name to meet naming conventions (e.g., converting to lowercase), which may affect integrations using the old name |
| `retrieve-conversation-information` | `slackbot.retrieveConversationInformation()` | — | 3 | Retrieves metadata for a Slack conversation by ID (e.g., name, purpose, creation date, with options for member count/locale), excluding message content |
| `retrieve-conversation-members-list` | `slackbot.retrieveConversationMembersList()` | — | 3 | Retrieves a paginated list of active member IDs (not names, emails, or presence) for a specified Slack public channel, private channel, DM, or MPIM |
| `retrieve-current-user-dnd-status` | `slackbot.retrieveCurrentUserDndStatus()` | — | 2 | Retrieves a Slack user's current Do Not Disturb (DND) status to determine their availability before interaction; any specified user ID must be a valid Slack user ID |
| `retrieve-detailed-information-about-file` | `slackbot.retrieveDetailedInformationAboutFile()` | `--file` | 4 | Retrieves detailed metadata and paginated comments for a specific Slack file ID; does not download file content |
| `retrieve-detailed-user-information` | `slackbot.retrieveDetailedUserInformation()` | — | 2 | Retrieves comprehensive information for a valid Slack user ID, excluding message history and channel memberships |
| `retrieve-user-profile-information` | `slackbot.retrieveUserProfileInformation()` | — | 2 | Retrieves profile information for a specified Slack user (defaults to the authenticated user if `user` ID is omitted); a provided `user` ID must be valid |
| `revoke-file-public-sharing` | `slackbot.revokeFilePublicSharing()` | `--file` | 0 | Revokes a Slack file's public URL, making it private; this is a no-op if not already public and is irreversible |
| `schedule-message` ·common | `slackbot.scheduleMessage()` | — | 12 | Schedules a message to a Slack channel, DM, or private group for a future time (`post_at`), requiring `text`, `blocks`, or `attachments` for content; scheduling is limited to 120 days in advance |
| `search-all` ·common | `slackbot.searchAll()` | `--query` | 6 | Search all messages and files |
| `search-messages` ·common | `slackbot.searchMessages()` | `--query` | 8 | Workspace‑wide Slack message search with date ranges and filters |
| `send-ephemeral-message` | `slackbot.sendEphemeralMessage()` | `--channel` `--user` | 11 | Sends an ephemeral message visible only to the specified `user` in a channel; other channel members cannot see it |
| `send-me-message` | `slackbot.sendMeMessage()` | — | 2 | Sends a 'me message' (e.g., '/me is typing') to a Slack channel, where it's displayed as a third-person user action; messages are plain text and the channel must exist and be accessible |
| `send-message` ·common | `slackbot.sendMessage()` | `--channel` | 7 | Posts a message to a Slack channel, DM, or private group |
| `set-conversation-purpose` | `slackbot.setConversationPurpose()` | — | 2 | Sets the purpose (a short description of its topic/goal, displayed in the header) for a Slack conversation; the calling user must be a member |
| `set-list-access` ·common | `slackbot.setListAccess()` | `--access-level` `--list-id` | 2 | Grants or sets sharing access on a Slack List via `slackLists.access.set` |
| `set-read-cursor-in-conversation` | `slackbot.setReadCursorInConversation()` | — | 2 | Marks a message, specified by its timestamp (`ts`), as the most recently read for the authenticated user in the given `channel`, provided the user is a member of the channel and the message exists… |
| `set-topic-of-conversation` | `slackbot.setTopicOfConversation()` | — | 2 | Sets or updates the topic for a specified Slack conversation |
| `set-user-active` | `slackbot.setUserActive()` | — | 0 | Mark a user as active in Slack |
| `set-user-presence` | `slackbot.setUserPresence()` | `--presence` | 0 | Manually sets a user's Slack presence, overriding automatic detection; this setting persists across connections but can be overridden by user actions or Slack's auto-away (e.g., after 10 mins of… |
| `share-remote-file` | `slackbot.shareRemoteFile()` | `--channels` | 2 | Shares a remote file, which must already be registered with Slack, into specified Slack channels or direct message conversations |
| `start-call` | `slackbot.startCall()` | `--external-unique-id` `--join-url` | 6 | Registers a new call in Slack using `calls.add` for third-party call integration; `created_by` is required if not using a user-specific token |
| `unarchive-channel` | `slackbot.unarchiveChannel()` | `--channel` | 0 | Reverses conversation archival |
| `unpin-item` | `slackbot.unpinItem()` | `--channel` `--timestamp` | 0 | Unpins a message, identified by its timestamp, from a specified channel if the message is currently pinned there; this operation is destructive |
| `update-call-info` | `slackbot.updateCallInfo()` | `--id` | 3 | Updates the title, join URL, or desktop app join URL for an existing Slack call identified by its ID |
| `update-list` ·common | `slackbot.updateList()` | `--id` | 3 | Updates a Slack List's metadata via `slackLists.update` |
| `update-list-item` ·common | `slackbot.updateListItem()` | `--cells` `--list-id` | 0 | Updates one or more cells in an EXISTING Slack List row via `slackLists.items.update` |
| `update-remote-file` | `slackbot.updateRemoteFile()` | — | 8 | Updates metadata or content details for an existing remote file in Slack; this action cannot upload new files or change the fundamental file type |
| `update-user-group` | `slackbot.updateUserGroup()` | `--usergroup` | 8 | Updates an existing Slack User Group, which must be specified by an existing `usergroup` ID, with new optional details such as its name, description, handle, or default channels |
| `update-user-group-members` | `slackbot.updateUserGroupMembers()` | `--usergroup` `--users` | 2 | Replaces all members of an existing Slack User Group with a new list of valid user IDs |
| `updates-message` ·common | `slackbot.updatesMessage()` | `--channel` `--ts` | 7 | Updates a Slack message by timestamp |

## Triggers

`slackbot.on("<event>", handler)` in a script; required config goes before the handler as an object.

| Event | Name | Required config | Description |
|---|---|---|---|
| `"channel-created"` | New Channel Created Trigger | — | Triggered when a new channel is created in Slack |
| `"channel-message-received"` | Channel Message Received | — | Triggered when a message is posted in a Slack channel (public, private, or multi-party IM) |
| `"direct-message-received"` | Direct Message Received | — | Triggered when a new direct message (DM) is sent to a user in Slack |
| `"message-reaction-added"` | Message Reaction Added | — | Triggered when a reaction is added to a message in Slack |
| `"message-reaction-removed"` | Message Reaction Removed | — | Triggered when a reaction is removed from a message in Slack |
| `"reaction-added"` | Reaction Added Trigger | — | use `SLACK_MESSAGE_REACTION_ADDED` instead |
| `"reaction-removed"` | Reaction Removed Trigger | — | use `SLACK_MESSAGE_REACTION_REMOVED` instead |
| `"receive-bot-message"` | New Bot Message Received Trigger | — | use `SLACK_CHANNEL_MESSAGE_RECEIVED` with `is_bot_message=true` instead |
| `"receive-message"` | New Message Received Trigger | — | use `SLACK_CHANNEL_MESSAGE_RECEIVED` instead |

## Docs

- [run CLI](https://docs.boxd.sh/cli/run): Call connected integrations from the shell, connect new ones, and run automations.
- [Quickstart](https://docs.boxd.sh/guides/integrations/quickstart): Connect an integration, call it from the shell, and turn a script into an automation.
- [Connections](https://docs.boxd.sh/guides/integrations/connections): Connect an account once, for yourself or for your whole organization.
- [Scripts](https://docs.boxd.sh/guides/automations/scripts): Typed integrations, triggers, schedules and state in a .run.ts file.
- [Jobs](https://docs.boxd.sh/guides/automations/jobs): How a script becomes a background job: states, retries, sleep and wake.
- [Beyond the catalog](https://docs.boxd.sh/guides/automations/beyond-the-catalog): Reach your own APIs, databases and cloud accounts from a script.
