> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chainlit.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack

To make your Chainlit app available on Slack, you will need to create a Slack app and set up the necessary environment variables.

## How it Works

The Slack bot will listen to messages mentioning it in channels and direct messages.
It will send replies to a dedicated thread or DM depending on the context.

<Frame caption="Preview">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/demo.gif?s=7b2e69f60f5815e93bfd5061b81e9933" width="1140" height="720" data-path="images/slack/demo.gif" />
</Frame>

## Supported Features

| Message | Streaming | Elements | Audio | Ask User | Chat History | Chat Profiles | Feedback |
| ------- | --------- | -------- | ----- | -------- | ------------ | ------------- | -------- |
| ✅       | ❌         | ✅        | ❌     | ❌        | ✅            | ❌             | ✅        |

## Install the Slack Bolt Library

The Slack Bolt library is not included in the Chainlit dependencies. You will have to install it manually.

```bash theme={null}
pip install slack_bolt
```

## Create a Slack App

To start, navigate to the [Slack apps dashboard for the Slack API](https://api.slack.com/apps). Here, you should find a green button that says Create New App. When you click this button, select the option to create your app from scratch.

Create a name for your bot, such as "ChainlitDemo". Select the workspace you would like your bot to exist in.

<Frame caption="Create a Slack App">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/create-app.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=5f4cf8fd864b500c46fa13068e30f6d2" width="994" height="375" data-path="images/slack/create-app.png" />
</Frame>

## Connection Modes

Chainlit supports two ways to connect to Slack:

* **HTTP Mode** (default): Slack sends events to your Chainlit server via HTTP. Requires a public URL.
* **Socket Mode** (since 2.7.0): Chainlit connects to Slack via WebSocket. No public URL needed — ideal for local development or restrictive networks.

To use Socket Mode, set the `SLACK_WEBSOCKET_TOKEN` environment variable (see [Environment Variables](#set-the-environment-variables)). When set, Socket Mode takes priority over the HTTP handler.

## Working Locally

### With Socket Mode (recommended)

If you use Socket Mode, no public URL or ngrok is needed. Chainlit connects to Slack over WebSocket directly. See the [Socket Mode app manifest](#socket-mode) below.

### With HTTP Mode

If you are working locally with HTTP mode, you will have to expose your local Chainlit app to the internet to receive incoming messages from Slack. You can use [ngrok](https://ngrok.com/) for this.

```bash theme={null}
ngrok http 8000
```

This will give you a public URL that you can use to set up the app manifest. Do not forget to replace it once you deploy Chainlit to a public host.

## Set the App Manifest

Go to App Manifest and paste the following Yaml.

<Note>Replace the `{placeholders}` with your own values.</Note>

```yaml theme={null}
display_information:
  name: { APP_NAME }
features:
  bot_user:
    display_name: { APP_NAME }
    always_online: false
oauth_config:
  scopes:
    user:
      - im:history
      - channels:history
    bot:
      - app_mentions:read
      - channels:read
      - chat:write
      - files:read
      - files:write
      - im:history
      - im:read
      - im:write
      - users:read
      - users:read.email
      - channels:history
      - groups:history
settings:
  event_subscriptions:
    request_url: https://{ CHAINLIT_APP_HOST }/slack/events
    bot_events:
      - app_home_opened
      - app_mention
      - message.im
  interactivity:
    is_enabled: true
    request_url: https://{ CHAINLIT_APP_HOST }/slack/events
  org_deploy_enabled: false
  socket_mode_enabled: false
  token_rotation_enabled: false
```

Click on Save Changes.

<Frame caption="Set the App Manifest">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/app-manifest.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=4e189046dd7b9df7abd631a84c6a7f0f" width="1037" height="955" data-path="images/slack/app-manifest.png" />
</Frame>

You will see a warning stating that the URL is not verified. You can ignore this for now.

### Socket Mode

If you are using Socket Mode, apply these changes to the manifest above: remove both `request_url` fields and set `socket_mode_enabled` to `true`.

```yaml theme={null}
settings:
  event_subscriptions:
    request_url: https://{ CHAINLIT_APP_HOST }/slack/events # [!code --]
    bot_events:
      - app_home_opened
      - app_mention
      - message.im
  interactivity:
    is_enabled: true
    request_url: https://{ CHAINLIT_APP_HOST }/slack/events # [!code --]
  org_deploy_enabled: false
  socket_mode_enabled: false # [!code --]
  socket_mode_enabled: true # [!code ++]
  token_rotation_enabled: false
```

## \[Optional] Allow users to send DMs to Chainlit

By default the app will only listen to mentions in channels.

If you want to allow users to send direct messages to the app, go to App Home and enable "Allow users to send Slash commands and messages from the messages tab".

<Frame caption="Allow DMs">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/allow-dm.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=dec3afe922d55c01f7dc83161225f33e" width="1414" height="1126" data-path="images/slack/allow-dm.png" />
</Frame>

## \[Optional] Emoji Reaction on Message Received

Adds an optional feature to show emoji reactions when Slack messages are received, providing immediate user feedback while the bot processes the request.

<Note>
  This feature requires the `reactions:write` OAuth scope. If you enable this feature, you'll need to add this scope to your Slack app's OAuth configuration.
</Note>

To enable this feature, add the following configuration to your `chainlit.md` file:

```toml theme={null}
[features.slack]
reaction_on_message_received = true
```

<Warning>
  This feature is disabled by default to maintain backward compatibility. If you enable this feature, you'll need to add the `reactions:write` scope to your Slack app's OAuth configuration.
</Warning>

<Frame caption="How it will look like">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/emoji-reaction.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=20fada4ce1257e9d2c6523b85140fff2" width="445" height="137" data-path="images/slack/emoji-reaction.png" />
</Frame>

## \[Optional] Handling Emoji Reactions from Users

React to emoji reactions that users add to messages in your Slack workspace.

<Note>
  This feature requires the `reactions:read` OAuth scope and the `reaction_added` bot event. Add both to your Slack app's manifest and OAuth configuration.
</Note>

```python theme={null}
from typing import Any, Dict
import chainlit as cl

@cl.on_slack_reaction_added
async def handle_reaction(event: Dict[str, Any]):
    reaction = event.get("reaction")       # e.g. "thumbsup"
    user_id = event.get("user")            # Slack user ID
    item = event.get("item", {})           # reacted item info

    print(f"User {user_id} reacted with :{reaction}: in channel {item.get('channel')}")
```

The `event` dictionary contains:

| Key        | Description                                                           |
| ---------- | --------------------------------------------------------------------- |
| `reaction` | Emoji name without colons (e.g. `"thumbsup"`)                         |
| `user`     | Slack user ID who added the reaction                                  |
| `item`     | Dict with `type`, `ts` (timestamp), and `channel` of the reacted item |

<Note>
  Since version **2.8.5**.
</Note>

## Install the Slack App to Your Workspace

Navigate to the Install App tab and click on Install to Workspace.

## Set the Environment Variables

<Note>Set the environment variables outside of your application code.</Note>

### Bot Token

Once the slack application is installed, you will see the Bot User OAuth Token. Set this as an environment variable in your Chainlit app.

<Frame caption="Copy the Bot Token">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/bot-token.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=84e8b9582dbf2aeeeb965e0f0b5fe152" width="951" height="459" data-path="images/slack/bot-token.png" />
</Frame>

```bash theme={null}
SLACK_BOT_TOKEN=your_bot_token
```

### Signing Secret

Navigate to the Basic Information tab and copy the Signing Secret. Then set it as an environment variable in your Chainlit app.

<Frame caption="Copy the Signing Secret">
  <img src="https://mintcdn.com/chainlit-43/bY2N4qUEa_bGPLfY/images/slack/signing-secret.png?fit=max&auto=format&n=bY2N4qUEa_bGPLfY&q=85&s=0ec562d61b87a98c432e9cfdd1c81759" width="707" height="689" data-path="images/slack/signing-secret.png" />
</Frame>

```bash theme={null}
SLACK_SIGNING_SECRET=your_signing_secret
```

### App-Level Token (Socket Mode only)

If you are using Socket Mode, you also need an App-Level Token. Navigate to **Basic Information** > **App-Level Tokens**, create a token with the `connections:write` scope, and set it as an environment variable.

```bash theme={null}
SLACK_WEBSOCKET_TOKEN=your_app_level_token
```

<Note>
  When `SLACK_WEBSOCKET_TOKEN` is set, Chainlit uses Socket Mode and the HTTP `/slack/events` endpoint is not registered. You do not need `SLACK_SIGNING_SECRET` in Socket Mode.
</Note>

## Start the Chainlit App

Since the Chainlit app is not running, the Slack app will not be able to communicate with it.

For the example, we will use this simple app:

```python my_app.py theme={null}
import chainlit as cl

@cl.on_message
async def on_message(msg: cl.Message):
    # Access the original slack event
    print(cl.user_session.get("slack_event"))
    # Access the slack user
    print(cl.user_session.get("user"))

    # Access potential attached files
    attached_files = msg.elements

    await cl.Message(content="Hello World").send()
```

<Note>
  Reminder: Make sure the environment variables are set. If using HTTP mode,
  your local Chainlit app must be exposed to the internet via ngrok.
</Note>

Start the Chainlit app:

```bash theme={null}
chainlit run my_app.py -h
```

<Note>
  Using -h to not open the default Chainlit UI since we are using Slack.
</Note>

You should now be able to interact with your Chainlit app through Slack.

## Chat History

Chat history is directly available through the `fetch_slack_message_history` method.
It will fetch the last messages from the current thread or DM channel.

```python theme={null}
import chainlit as cl
import discord


@cl.on_message
async def on_message(msg: cl.Message):
    fetch_slack_message_history = cl.user_session.get("fetch_slack_message_history")

    if fetch_slack_message_history:
        print(await fetch_slack_message_history(limit=10))

    # Your code here
```
