In this repository you will find a ready-to-use Slack bot template for a DataRobot Custom Application. After creating the Slack application, you can immediately start configuring the bot messages and events.
The Slack bot code is based on the Bolt for Python starter template and comes with a small FastAPI app and start-app script to create a working DataRobot Custom Application.
Follow the configuration outlined in the steps below.
Important: This template requires a modern Slack app with Socket Mode support. Slack apps created before 2021 (legacy apps) do not support Socket Mode and cannot be used with this template. Always create a new app.
Create a new Slack application and select From a manifest. This is the recommended approach — the repository includes a slack_manifest.json that configures all required scopes, events, and settings in one step.
- Select From a manifest and choose your workspace.
- Select the JSON tab and paste the contents of slack_manifest.json.
- Update the app name in
display_information > nameand the bot display name infeatures > bot_user > display_name. - Review the permissions and confirm the app creation.
The manifest pre-configures all OAuth scopes and event subscriptions the bot needs. Adding scopes later requires reinstalling the app to your workspace — if your organisation requires IT approval for Slack app installs, plan your scope requirements upfront.
The bot requires two tokens. Generate them in the order below — Socket Mode must be enabled before generating the App Token, otherwise the required scope will not appear.
Step 1 — Enable Socket Mode
Go to Settings → Socket Mode and toggle it on. This makes the bot connect to Slack over a persistent WebSocket instead of requiring a public URL.
Step 2 — Generate SLACK_APP_TOKEN
Go to Basic Information → App-Level Tokens and click Generate Token and Scopes. Add the connections:write scope — this is the only scope that allows the bot to open a WebSocket connection. Copy the generated token (it starts with xapp-).
If you only see
authorizations:readandapp_configurations:writeas scope options, Socket Mode is not enabled yet. Go back to Step 1.
Step 3 — Generate SLACK_BOT_TOKEN
Go to OAuth & Permissions and click Install to workspace. Review the permissions and confirm. Once installed, copy the Bot User OAuth Token from the same page (it starts with xoxb-).
Adding or changing OAuth scopes after installation requires a reinstall. Go to OAuth & Permissions → Reinstall to workspace after any scope changes.
You can run the bot inside DataRobot using a Custom Application or by running the app locally. Custom Applications can be created via the Registry's Applications page or by using DRApps.
Define the variables for the app to communicate with Slack. If you run the app locally or via another environment, then you need to set the environment variables in the terminal that you use. When this app is run via the Applications page, the variables can be set with the preconfigured runtime parameters in the application source.
For a local run:
cd src
uv sync
export SLACK_APP_TOKEN="xapp-..."
export SLACK_BOT_TOKEN="xoxb-..."
./start-app.shFor the Applications page:
Use [DataRobot] Python 3.12 as the base environment and set the tokens in the runtime parameters section. To do that,
click the edit icon, expand the value dropdown, and select Add credentials. Follow the instructions to add the tokens as API Tokens and return to the application source. Now select the newly created credentials to the corresponding variable.
Lastly, scroll to the top of the application source and click Build application.
The bot responds to @mentions only. Invite it to a channel with /invite @your-bot-name, then try the following:
@your-bot-name ask what is the capital of France?— the bot will answer via the DataRobot LLM Gateway@your-bot-name help— the bot will list available commands@your-bot-name Hello!— the bot will echo your message back- Open the bot's App Home tab to see an overview of available commands
The bot includes an @mention ask <question> command powered by the DataRobot LLM Gateway. It uses the datarobot SDK and LiteLLM for LLM calls. The DATAROBOT_API_TOKEN and DATAROBOT_ENDPOINT are injected automatically by the platform so no additional configuration is required to get started.
To use a different model, set the DATAROBOT_LLM_MODEL environment variable to the full LiteLLM model string (e.g. datarobot/azure/gpt-4o). The default is azure/gpt-5-1-2025-11-13.
To discover available models programmatically:
import datarobot
catalog = datarobot.genai.LLMGatewayCatalog()
print(catalog.list_as_dict())Custom applications auto-stop after a while of inactivity. To turn this off for your Slack bot, please run the following
command using your <application_id> and <authorization_token>:
curl --location --request PATCH 'https://app.datarobot.com/api/v2/customApplications/<application_id>/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <authorization_token>' \
--data '{
"allowAutoStopping": false
}'The bot connects but does not respond to @mentions
Make sure the app_mention event is subscribed under Event Subscriptions → Subscribe to bot events. Socket Mode still requires explicit event subscriptions — it only changes how events are delivered (WebSocket instead of HTTP), not which events are sent. Invite the bot to the channel with /invite @your-bot-name if you have not already done so.
The bot does not respond to plain messages (hi, potato, etc.)
Plain message handlers are disabled by default. Enable them by adding entries to matcher_map in src/listeners/messages/__init__.py. These handlers also require additional OAuth scopes (channels:history, im:history, im:read, im:write) and event subscriptions (message.channels, message.im) — all of which are already included in the manifest. If your organisation requires IT approval for these scopes, the @mention-only mode works without them.
connections:write scope is not available when generating the App Token
Socket Mode is not enabled. Go to Settings → Socket Mode, enable it, and then return to Basic Information → App-Level Tokens to generate the token.
missing_scope: chat:write error in the logs
The bot token was generated before chat:write was added to the app's scopes, or the app was created without the manifest. Go to OAuth & Permissions → Reinstall to workspace to apply the current scope configuration.
missing_scope: connections:write / provided: app_configurations:write error
The App Token was generated with the wrong scope. Delete it from Basic Information → App-Level Tokens and generate a new one with connections:write.
Event subscriptions page shows a "Request URL" field and Save is disabled
This happens when Socket Mode is not enabled — the page falls back to HTTP mode and requires a verified URL before saving. Enable Socket Mode first (Settings → Socket Mode), then return to configure event subscriptions.
You can find examples for all available Slack listeners in the Bolt for Python starter template. The approach is the exact same as in this repository, but they provide other, more advanced actions.
This workflow only focuses on how to add more message and event listeners. Note that some events might require additional scopes and permissions. These are all mentioned within the events list on https://api.slack.com/events. To add new scopes to an existing app, go to the Slack OAuth & Permissions page and find the Scopes section. Once you add new scope to the app it might require to be reinstalled.
To configure events, navigate to src/listeners/events/__init__.py and register your handler with the @app.event decorator inside the register function:
@app.event("reaction_added")
def reaction_added(event: dict, say: Say, logger: Logger) -> None:
logger.info("Reaction added: %s", event)For more complex handlers, define the callback in a separate module and register it:
from .my_handler import my_callback
app.event("app_mention")(my_callback)Messages are registered in src/listeners/messages/__init__.py using the @app.message decorator inside the register function. Pass a plain string for exact matches or a compiled regex for patterns:
@app.message("Hello!")
def hi(message: dict[str, Any], say: Say) -> None:
say(f"Hi there <@{message['user']}>! :wave:")
@app.message(re.compile(r"(goodbye|bye|farewell)", re.IGNORECASE))
def goodbye(context: BoltContext, say: Say, logger: Logger) -> None:
farewell = context["matches"][0]
logger.info("Responding to farewell: %s", farewell)
say(f"{farewell}, see you next time!")Be aware that unrelated conversations could trigger the bot if the matching phrase is too common!