Blog

Building a Slack Bot with Claude Code

How to build a Slack bot with Claude Code using the Bolt framework: app manifest, event subscriptions, slash commands, Block Kit UI, and a deployment comparison table.

Phos Team ·
claude code

Slack bots are the highest-leverage internal tool for teams already living in Slack. A well-built bot surfaces the right information at the right time, in the channel where work is already happening, without requiring anyone to switch context to another tool.

Claude Code handles Slack’s Bolt framework well. The event subscription model, slash command handlers, and Block Kit UI components all generate cleanly from well-formed prompts. The setup is more involved than a Telegram bot (Slack’s app configuration is richer), but the resulting product is more deeply integrated into how most teams work.

The Slack bots that get used daily are the ones that eliminate a specific repeated task: the end-of-day standup prompt, the deployment notification, the support ticket triage. Start with one workflow, deploy it, and measure whether the team uses it before building more.


Slack Bolt framework setup

Why Bolt

Bolt is Slack’s official SDK for building Slack apps. It handles OAuth, event parsing, middleware, and the complexity of Slack’s interactive components. Claude Code generates idiomatic Bolt code for both Python (slack-bolt) and JavaScript (@slack/bolt).

Bolt abstracts Slack’s API complexity significantly. You define handlers for events, actions, and commands. Bolt handles the routing, verification, and response patterns.

Creating your Slack app

Before writing code, you create a Slack app at api.slack.com/apps. The app manifest (a YAML or JSON file) defines your app’s capabilities: which events it subscribes to, which slash commands it uses, what scopes it requests.

Claude Code cannot create your Slack app, but it can generate the app manifest and the Bolt application code. Start with the manifest.


The build workflow

Step 1: Generate the app manifest

An app manifest is the spec for your Slack app’s configuration. Ask Claude Code to generate one based on your bot’s requirements: “Generate a Slack app manifest (YAML) for a bot that: subscribes to app_mention and message.im events, has slash commands /ask and /status, has the scopes chat:write, commands, app_mentions:read, and im:read. App name: [your name].”

Copy the generated manifest into your Slack app’s configuration at api.slack.com/apps. This configures your app before you write a line of application code.

Step 2: Scaffold the Bolt application

With your app created and manifest applied, scaffold the Bolt application: “Create a Slack bot using the Python slack-bolt library. Set up the app with SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET from environment variables. Include handlers for: app_mention events, direct messages, the /ask slash command, and the /status slash command. Use socket mode for local development.”

Socket mode lets you develop locally without a public URL. Claude Code generates the socket mode configuration and the production webhook configuration as a toggle based on an environment variable.

Step 3: Implement event handlers

Event handlers respond to Slack events your app is subscribed to. Claude Code generates clean event handlers: “Add a handler for app_mention events. When the bot is mentioned, extract the message text (minus the bot mention), pass it to the OpenAI API, and reply in the same thread with the response. If the thread has existing messages, include the last 10 messages as conversation history.”

Thread-aware responses are a common pattern Claude Code handles correctly: use say(thread_ts=event['ts']) to reply in the thread rather than to the channel.

Step 4: Implement slash commands

Slash commands give users a direct interface to your bot. A slash command prompt: “Add a handler for the /status slash command. The command should: show a Block Kit message with three sections: system status (fetched from an internal /health endpoint), today’s date and time in UTC, and the number of active users (fetched from the database). Use the response type ephemeral so only the requesting user sees the response.”

Slash commands have a three-second response deadline. If your handler takes longer, use ack() immediately and send the full response via respond() after the async work completes. Claude Code generates this pattern when you specify it.

Step 5: Build Block Kit UI

Block Kit is Slack’s UI framework for rich interactive messages. Buttons, dropdowns, modals, and multi-section layouts are all Block Kit components. Claude Code generates Block Kit layouts accurately when you describe the components you need.

A Block Kit prompt: “Create a Block Kit message template for a deployment notification. Sections: a header with the service name and version, a fields section with Deploy Time (UTC), Triggered By (username), and Environment (production/staging), a divider, and a button row with ‘View Logs’ linking to the log URL and ‘Roll Back’ triggering the action ID rollback_confirm.”

Review generated Block Kit JSON at app.slack.com/block-kit-builder before wiring it into your application. This visual validation catches layout issues faster than debugging from the Slack UI.

Step 6: Handle interactive components

Block Kit buttons and interactive elements generate action payloads. Wire them to action handlers: “Add an action handler for rollback_confirm. When triggered, send a modal with a confirmation message (‘Are you sure you want to roll back [service] to [previous version]?’) and two buttons: ‘Confirm Rollback’ and ‘Cancel’.”

Interactive flows (button triggers modal, modal triggers confirmation) are where Slack bots become genuinely useful for operational workflows. Claude Code generates the Bolt action and view submission handler pattern correctly.


Common bot patterns

Proactive notifications

Bots can send messages without user prompting using client.chat_postMessage. This is how you build deployment notifications, daily reports, and alert routing. Claude Code generates notification functions that accept a channel ID and message payload: “Create a function send_deploy_notification(channel_id, service, version, deployer) that posts a Block Kit deployment message to the specified channel.”

AI-powered responses

Combining Slack events with an LLM backend creates a bot that can answer questions, summarize threads, or draft messages on request. The Bolt handler passes the message to the LLM. The LLM response goes back to Slack via say(). Claude Code generates this integration cleanly when you specify the LLM client (OpenAI, Anthropic).

Interactive approval flows

Approval workflows (a user requests something, a manager approves or rejects via Slack) are a high-value Slack bot use case. The pattern: user triggers slash command, bot posts a message with Approve/Reject buttons to a manager channel, manager clicks button, bot updates the original message and notifies the requester. Claude Code generates this full flow when prompted step by step.


Deployment comparison table

PlatformFree tierSocket modeWebhook modeBest for
Railway$5/month creditYes (dev only)YesSimple production deployment
RenderSpins down on freeYes (dev only)YesLow-traffic bots
Fly.ioGenerous free tierYes (dev only)YesGlobal or high-availability bots
HerokuNo longer freeYes (dev only)YesTeams already on Heroku
AWS LambdaVery generous free tierNoYesServerless, low-cost at scale
VPS~$5/monthBothBothFull control, high customization

Railway is the simplest path to production for most Slack bots. The environment variable management, HTTPS, and persistent processes are handled without configuration overhead. Claude Code generates railway.toml deployment configuration for Railway projects.


Frequently asked questions

What is the difference between socket mode and webhook mode for Slack bots?

Socket mode uses a persistent WebSocket connection from your server to Slack. It works without a public URL and is ideal for local development and internal-only bots. Webhook mode has Slack send HTTP POST requests to your public URL for each event. It is the production approach and required for bots distributed through the Slack App Directory.

How do I handle Slack’s three-second response timeout for slash commands?

Call ack() immediately when the slash command handler fires, then perform the slow work asynchronously. Send the result using respond() or client.chat_postMessage() after the async work completes. Claude Code generates this ack() then async pattern when you specify that the command involves an API call or database query.

Can Claude Code generate a Slack bot that works across multiple workspaces?

Yes, with an important setup difference. Multi-workspace bots require OAuth installation flow (each workspace installs the app separately). This adds an installation handler and a token storage requirement. Specify “multi-workspace with OAuth” in your scaffold prompt and Claude Code will generate the installation handler, token store interface, and the updated Bolt configuration.

How should I store Slack workspace tokens?

Never hardcode tokens. For single-workspace bots, use environment variables. For multi-workspace bots, store tokens in a database keyed by team_id. Claude Code generates a token_store interface for multi-workspace token storage and can scaffold the database implementation for PostgreSQL or SQLite.


Ready to build your Slack bot?

Slack bots built with Bolt and Claude Code produce operational tools that teams actually use. The event subscription model makes it straightforward to react to the right triggers.

Block Kit gives you enough UI richness to build approval flows, notifications, and dashboards without leaving Slack. If your bot connects to external data sources, the MCP setup guide covers how to extend Claude Code with additional integrations.

For bots that are part of a larger application, how to build a full-stack app with Claude Code covers the broader backend architecture.

The most successful Slack bots are the ones built with a specific, measurable use case: this workflow takes 15 minutes manually, the bot does it in 10 seconds. That clarity of purpose drives both build speed and adoption.

Path one: do it yourself. Create your Slack app at api.slack.com, generate the app manifest with Claude Code, and scaffold the Bolt application. Define one event handler and one slash command. Deploy to Railway and test with your team before adding more handlers.

Path two: work with Phos AI Labs. If you want an experienced team building and deploying your Slack bot from design through production rollout, Phos AI Labs runs structured build engagements. Start with a conversation.

Related articles

The fastest way to know whether we're the right fit, is a conversation.

STEP 1/2 · ABOUT YOU