GUIDE
Build a Slack Bot With Claude Code
Build an internal Slack bot that answers your team's questions, pulls metrics, and automates workflows. Step-by-step guide using Claude Code and the Bolt framework.
Your team asks the same questions in Slack every week. "What's our MRR?" "How many signups yesterday?" "When's the next release?" Someone copies a number from a dashboard, pastes it into the channel, and everyone moves on until the same question pops up three days later.
Build a bot that answers them. I've walked over 100 students through Claude Code at this point, and the Slack bot project is the one that gets people most fired up. Because every person on your team, from PMs to founders to support reps, lives in Slack. A bot there is a bot that actually gets used.
We're going to build a Slack bot that responds to slash commands, pulls real data, and deploys so your whole team can use it. Total build time with Claude Code: about an hour.
Why a Slack Bot (And Why Now)
Slack bots used to be a pain to build. You needed to understand OAuth flows, event subscriptions, webhook verification, request signing, and a dozen other pieces of plumbing before you could make the bot say "hello." That plumbing still exists, but Claude Code writes it all for you.
The value is immediate. A /metrics command that returns your key numbers saves 5 minutes every time someone asks. Multiply that by 10 people asking 3 times a week and you've bought back over 2 hours a week from a single slash command. But the real payoff is cultural: your team starts expecting answers instantly instead of waiting for someone to go check a dashboard.
Step 1: Create Your Slack App
Before writing any code, you need a Slack app. Head to https://api.slack.com/apps and click "Create New App." Choose "From scratch," give it a name (something like "Team Bot"), and select your workspace.
Once created, grab these three things from the app settings:
- Bot Token (
xoxb-...): Under "OAuth & Permissions," install the app to your workspace and copy the Bot User OAuth Token - Signing Secret: Under "Basic Information," find the Signing Secret
- App Token (
xapp-...): Under "Basic Information" then "App-Level Tokens," generate one with theconnections:writescope (needed for Socket Mode)
For bot token scopes, add at minimum: chat:write, commands, and app_mentions:read. You can bolt on more scopes later as you extend the bot.
Step 2: Scaffold the Bot With Claude Code
Open your terminal, create a project folder, and start Claude Code:
mkdir slack-bot && cd slack-bot
claudeNow give Claude Code this prompt:
Build a Slack bot using the @slack/bolt framework in TypeScript.
It should:
1. Run in Socket Mode (no public URL needed for development)
2. Respond to a /metrics slash command with formatted sample data
3. Respond to @mentions with a helpful reply
4. Use environment variables for SLACK_BOT_TOKEN,
SLACK_SIGNING_SECRET, and SLACK_APP_TOKEN
Create a .env.example file documenting the required variables.
Keep the code in a single src/index.ts file to start.Claude Code will scaffold the entire project: package.json with dependencies, tsconfig.json, the bot code, and the .env.example file. It picks Bolt because that's Slack's official framework and the one with the best documentation and community support.
What the Generated Code Looks Like
Here's the core structure Claude Code produces:
import { App } from "@slack/bolt";
import dotenv from "dotenv";
dotenv.config();
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
});
// Slash command: /metrics
app.command("/metrics", async ({ ack, respond }) => {
await ack();
await respond({
response_type: "in_channel",
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: "*📊 Weekly Metrics*\n\n"
+ "• MRR: $45,200 (+3.2%)\n"
+ "• Active Users: 1,847\n"
+ "• Signups (7d): 94\n"
+ "• Churn Rate: 2.1%",
},
},
],
});
});
// Respond to @mentions
app.event("app_mention", async ({ event, say }) => {
await say({
text: `Hey <@${event.user}>! I can help with:\n`
+ "• /metrics — pull weekly numbers\n"
+ "Type a slash command to get started.",
thread_ts: event.ts,
});
});
(async () => {
await app.start();
console.log("⚡ Slack bot is running in Socket Mode");
})();Socket Mode is the key detail here. It means the bot connects outbound to Slack rather than requiring a public URL. No ngrok, no tunnels, no deployment needed just to test. You run it locally and it works.
Step 3: Register the Slash Command in Slack
Back in your Slack app settings at https://api.slack.com/apps, go to "Slash Commands" and create a new command:
- Command:
/metrics - Short Description: "Pull weekly metrics"
- Usage Hint: leave blank
Also enable Socket Mode under "Socket Mode" in the sidebar and make sure "Event Subscriptions" is turned on with the app_mention event subscribed. Save changes.
Step 4: Run and Test
Create your .env file with the tokens you grabbed earlier, then tell Claude Code:
Install dependencies and run the bot. My .env file is ready
with the Slack tokens.Claude Code runs npm install and starts the bot. Go to any channel where you've added the bot and type /metrics. You should see formatted metrics appear. Mention the bot with @Team Bot and it responds with a help message in a thread.
If something breaks (wrong token, missing scope, event not firing), paste the error back to Claude Code. It'll diagnose the Slack API error and tell you exactly which setting to flip.
Step 5: Wire Up Real Data
Hardcoded metrics are a demo. Real metrics are a tool. This is where the bot becomes genuinely useful.
Tell Claude Code to connect the /metrics command to your actual data source:
Update the /metrics command to pull real data from our
PostgreSQL database.
Connection string is in DATABASE_URL env var.
Queries needed:
- MRR: SELECT SUM(amount) FROM subscriptions
WHERE status = 'active'
- Signups (7d): SELECT COUNT(*) FROM users
WHERE created_at > NOW() - INTERVAL '7 days'
- Active users: SELECT COUNT(DISTINCT user_id)
FROM events WHERE timestamp > NOW() - INTERVAL '7 days'Claude Code bolts on a database connection, writes the queries, and formats the results into Slack's Block Kit format. If you don't have a database, you can pull from a Google Sheet, a REST API, or even a CSV file. The pattern is the same: tell Claude Code where the data lives and what to pull.
If you're interested in connecting Claude Code itself to databases and external services, the MCP servers guide covers how that works under the hood.
Step 6: Add More Commands
One command is a start. A handful of commands makes the bot indispensable. Here are commands I've seen students ship in the same session:
/oncallreturns who's on call this week (pulled from a PagerDuty API or a simple JSON rotation schedule)/releaseshows the next release date and what's shipping (pulled from Linear, Jira, or a markdown file in the repo)/customer [name]looks up a customer's plan, MRR, and last activity date from the database/standupposts a threaded prompt for team members to fill in their daily update
Each new command is a single prompt to Claude Code. Describe what data to pull and how to format it. Claude handles the Bolt API wiring, the data fetching, and the Slack Block Kit formatting.
Deploying for Your Team
Socket Mode is great for development, but for production you want the bot running somewhere reliable. Tell Claude Code:
Set up this bot to deploy on Railway (or Render).
Create a Dockerfile and a start script.
The bot should restart automatically if it crashes.Claude Code generates a Dockerfile, updates package.json with a production start script, and gives you the deployment steps. Railway and Render both have free tiers that handle a Slack bot easily. Push to GitHub, connect the repo, set your environment variables in the platform's dashboard, and the bot is live for your whole team.
For a full walkthrough on how Claude Code handles deployment scaffolding, check the Claude Code tutorial.
Extending With AI Responses
The most powerful version of this bot answers questions it hasn't been explicitly programmed for. Instead of only responding to specific slash commands, it can take freeform questions and respond using your internal docs, product data, or knowledge base.
Tell Claude Code:
Add a /ask command that takes a question as input.
Load our product FAQ from a markdown file (docs/faq.md)
and use it as context to answer the question.
Use the Anthropic API (key in ANTHROPIC_API_KEY env var)
to generate the response.Now your team can type /ask What's our refund policy? and the bot checks your FAQ, generates a relevant answer, and posts it in Slack. This works for internal wikis, product docs, onboarding guides, or anything you can put in a text file. For more on how Claude Code handles agents and autonomous workflows, see the agents guide.
Common Pitfalls
- Missing scopes: if the bot can't post messages, you probably forgot the
chat:writescope. Re-add it under OAuth & Permissions and reinstall the app to your workspace. - Bot not in the channel: you need to invite the bot to a channel before it can respond there. Type
/invite @Team Botin the channel. - Slash command timeout: Slack requires a response within 3 seconds. If your data query is slow, acknowledge immediately with
ack()and then send the data as a follow-up usingrespond(). Claude Code already structures the code this way, but keep it in mind if you modify things manually. - Socket Mode vs HTTP: if you switch from Socket Mode to HTTP for production, you'll need a public URL and request verification. Claude Code handles the transition if you ask for it.
What You've Built
A production Slack bot that pulls real data, responds to slash commands, and can be extended with new commands in minutes. Your team stops pinging each other for numbers and starts getting instant answers.
The pattern here scales. Every internal tool your team needs, whether it's a metrics dashboard, a customer lookup, or an AI-powered FAQ, can live as a Slack command that Claude Code builds for you in a single session.
Want hands-on training building tools like this? ClaudeFluent is a premium live course where I walk you through Claude Code projects step by step, from Slack bots to full web apps. The best practices guide covers the prompting patterns that make every project faster.