From zero to working Slack bot in one lesson
Your local dev environment needs to support rapid iteration. This lesson gets you from nothing to a working Slack bot that responds to messages. When you're building AI-powered bots, minimal setup friction matters—every extra step between idea and testing kills momentum.
After this lesson, you'll:
- DM your bot "ping" → see a bot response quickly
- See correlation IDs in logs tracking the full request lifecycle
- Have a working local dev environment ready for the next lesson
# You'll see this in Slack:
You: ping
Bot: <AI streams a response word-by-word>
# And this in your terminal:
[DEBUG] bolt-app app_mention event received ... "ts":"1763483445.596649"
[DEBUG] web-api:WebClient:1 apiCall('chat.startStream') start
[DEBUG] web-api:WebClient:1 ChatStreamer appended to buffer: {"bufferLength":2,...}
[DEBUG] web-api:WebClient:1 apiCall('chat.stopStream') startOutcome
Provision a Slack Developer Sandbox, create your own repo from the template, configure the app, and confirm the bot responds.
Fast Track
- Provision a Slack Developer Sandbox and create your own repo from the Slack Agent template.
- Create the app from
manifest.json, add env secrets, and link it withslack app link. - Run
slack run, DM the bot “ping”, and capture the reply + logs.
Source of Truth
- Use the project's README in your cloned repo as the source of truth for setup. This lesson summarizes it into a concise checklist with context.
Prerequisites
Step 0: Provision Sandbox
You'll need to join the Slack Developer program to provision a sandbox. You can do that here if you haven't already joined previously.
- Review Developer Sandboxes documentation
- Create a Slack Developer Sandbox via the Slack Developer Program dashboard.
- Sign in to your new sandbox workspace.
- Confirm you are workspace admin.
- Take note of your sandbox's “Status” and “Archive Date” and add this information to your project README.md for reference (optional).
Step 1: Create and Clone Your Repo
First, create your own copy of the Slack Agent template by clicking the Deploy with Vercel button:
You don’t need to configure anything else yet—this just creates your own copy of the starter code.
This creates a new GitHub repo under your account and a linked Vercel project that you’ll use later when you deploy to production in Deploy to Vercel.
After you’ve created your own repo (via the Deploy with Vercel button), clone your new repo locally:
# Replace <your-username> and repo name with the repo you just created from the template
git clone https://github.com/<your-username>/slack-agent-template slack-agent
cd slack-agent
pnpm installThe README in the cloned project has details about how to setup and deploy your new application, which you can find summarized below as well.
The next step is to configure the app.
Step 2: Configure App
2.1 Create the Slack app
- Open https://api.slack.com/apps/new → choose From an app manifest.
- Select your sandbox workspace.
- Paste the contents of manifest.json into the JSON tab and click Next.
- Review → Create.
- From Basic Information, copy the Signing Secret into
.envasSLACK_SIGNING_SECRET. - From Install App, click Install to
<SANDBOX_NAME>→ Allow. - Copy the Bot User OAuth Token into
.envasSLACK_BOT_TOKEN.
2.2 Wire up your local project
- Authenticate the CLI (only once per machine):
slack login - Link the app to this repo so
slack runknows which manifest to use:slack app link - If prompted, allow the CLI to update the remote manifest and choose the workspace you just configured.
- Switch the manifest source to in the
.slack/config.jsonfile tolocal:{ "manifest": { "source": "local" }, "project_id": "<project-id-added-by-slack-cli>" } - Add the rest of your env values:
AI_GATEWAY_API_KEYfrom Vercel AI GatewayNGROK_AUTH_TOKENfrom ngrok dashboard
Step 3: Run locally
slack run and accept prompts to apply manifest changes remotely. Events will now be forwarded to your local server.
IMPORTANT: When running slack run, you'll be prompted: "Do you want to apply manifest changes to this app?"
The default is N (No) - you must explicitly type y and press Enter to apply changes.
If you miss this prompt, your bot won't receive events. You can always re-run slack run to get the prompt again.
Quick Checklist
- Slack CLI and pnpm installed
- Sandbox workspace ready and you're an admin
- App created from manifest and installed to your sandbox workspace
.env:SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET,AI_GATEWAY_API_KEY,NGROK_AUTH_TOKEN(if using tunnel)slack app linkand set manifest.json source tolocal- Run:
slack runand accept prompts to apply manifest changes remotely. Note the default is NOT to apply changes, so be sure to selectyfor yes. Events will now be forwarded to your local server. - DM the bot
pingand verify logs
Hands-On Exercise 1.1
- DM the bot with
ping. Capture the response and an end-to-end log trace includingevent_idorts.
Example Response
- Ensure
slack runis active and events are hitting your local/api/slack/eventsroute (slack-agent/server/api/slack/events.post.ts). - In Slack, DM your bot:
ping. - Copy the message link in Slack (More actions → Copy link) to capture the message
ts. - From your terminal logs, include at least one relevant line. Prefer the
web-api:WebClient ... chat.startStream/chat.stopStream ...pair that shows the replyts. INFO-only output is fine if that’s all you captured. - Submit: the bot reply text, the Slack message
ts, and one relevant log line.
Example reply (message ts: 1763483445.596649):
It seems like you're trying to get <@U09U3MX9BK3>'s attention. If there's anything specific you'd like to discuss or need help with regarding this, feel free to let me know!Example log slice tying that DM to the response:
[DEBUG] bolt-app app_mention event received ... "ts":"1763483445.596649"
[DEBUG] web-api:WebClient:1 apiCall('chat.startStream') ... "ts":"1763483452.143929"
[DEBUG] web-api:WebClient:1 apiCall('chat.stopStream') ... "ts":"1763483452.143929"Correlation tips:
- Use
event_idto stitch request logs across your stack. - Use message
ts(and replythread_ts) to connect the inbound event to the bot's response.
Hands-On Exercise 1.2
- Capture a detailed trace from your running app's logs (no code changes).
Where logging comes from in the template:
slack-agent/server/app.tssetsconst logLevel = NODE_ENV === "development" ? LogLevel.DEBUG : LogLevel.INFO.- That
logLevelis passed tonew VercelReceiver({ logLevel }), so runningslack run(development) yields DEBUG receiver/SDK logs by default.
What to include from your terminal:
- Receiver/Vercel init lines proving the app booted.
- The
chat.startStream+chat.stopStreampair that shows the replyts. - Any extra DEBUG web-api lines that help tell the story (auth.test, etc.).
Notes:
web-api:WebClientlines are SDK HTTP calls and won’t includeevent_id.- If you only see INFO-level output, that’s acceptable—capture what you have.
Reference: Slack Bolt logging docs: https://docs.slack.dev/tools/bolt-js/concepts/logging/
Commit
git add -A
git commit -m "feat(setup): initialize Slack bot with sandbox configuration
- Configure Developer Sandbox workspace
- Set up manifest with bot scopes and events
- Verify bot responds to DM and mentions
- Confirm correlation fields in logs"Done-When
- The bot responds to DM and mention; logs show request start, tool calls (if any), and response with correlation fields.
Was this helpful?