Vercel Logo

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') start

Outcome

Provision a Slack Developer Sandbox, create your own repo from the template, configure the app, and confirm the bot responds.

Fast Track

  1. Provision a Slack Developer Sandbox and create your own repo from the Slack Agent template.
  2. Create the app from manifest.json, add env secrets, and link it with slack app link.
  3. 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.

Credit Card Required
Please note that provisioning a Slack sandbox will require a credit card on file. Sandboxes are free, but for verification and to prevent abuse they require a credit card on file. Alternatively you can use an existing Slack Workspace.
  • 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:

Deploy with Vercel

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 install

The 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

  1. Open https://api.slack.com/apps/new → choose From an app manifest.
  2. Select your sandbox workspace.
  3. Paste the contents of manifest.json into the JSON tab and click Next.
  4. Review → Create.
  5. From Basic Information, copy the Signing Secret into .env as SLACK_SIGNING_SECRET.
  6. From Install App, click Install to <SANDBOX_NAME>Allow.
  7. Copy the Bot User OAuth Token into .env as SLACK_BOT_TOKEN.

2.2 Wire up your local project

  1. Authenticate the CLI (only once per machine):
    slack login
  2. Link the app to this repo so slack run knows which manifest to use:
    slack app link
  3. If prompted, allow the CLI to update the remote manifest and choose the workspace you just configured.
  4. Switch the manifest source to in the .slack/config.json file to local:
    {
      "manifest": {
        "source": "local"
      },
      "project_id": "<project-id-added-by-slack-cli>"
    }
  5. Add the rest of your env values:

Step 3: Run locally

slack run and accept prompts to apply manifest changes remotely. Events will now be forwarded to your local server.

Manifest Update Prompt

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 link and set manifest.json source to local
  • Run: slack run and accept prompts to apply manifest changes remotely. Note the default is NOT to apply changes, so be sure to select y for yes. Events will now be forwarded to your local server.
  • DM the bot ping and verify logs

Hands-On Exercise 1.1

  • DM the bot with ping. Capture the response and an end-to-end log trace including event_id or ts.

Example Response

  1. Ensure slack run is active and events are hitting your local /api/slack/events route (slack-agent/server/api/slack/events.post.ts).
  2. In Slack, DM your bot: ping.
  3. Copy the message link in Slack (More actions → Copy link) to capture the message ts.
  4. From your terminal logs, include at least one relevant line. Prefer the web-api:WebClient ... chat.startStream/chat.stopStream ... pair that shows the reply ts. INFO-only output is fine if that’s all you captured.
  5. 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_id to stitch request logs across your stack.
  • Use message ts (and reply thread_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.ts sets const logLevel = NODE_ENV === "development" ? LogLevel.DEBUG : LogLevel.INFO.
  • That logLevel is passed to new VercelReceiver({ logLevel }), so running slack 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.stopStream pair that shows the reply ts.
  • Any extra DEBUG web-api lines that help tell the story (auth.test, etc.).

Notes:

  • web-api:WebClient lines are SDK HTTP calls and won’t include event_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.