Skip to main content

Slackbot Agent Guide

还没翻译译自英文(ai-sdk.dev)本页 40 段都还没译

In this guide, you will learn how to build a Slackbot powered by the AI SDK. The bot will respond to mentions in channels and to direct messages, using the full context of the thread, and stream its replies into Slack as they are generated.

The bot uses Chat SDK to connect to Slack. Chat SDK verifies Slack's webhook signatures, parses events into threads and messages, and streams replies with Slack's native streaming API, so you can focus on the agent.

Project Setup

This project uses the following stack:

Create a new Next.js application:

pnpm create next-app@latest my-slackbot

Navigate to the newly created directory:

cd my-slackbot

Install the AI SDK, Chat SDK, the Slack adapter, the Redis state adapter, and zod for tool inputs:

pnpm add ai chat @chat-adapter/slack @chat-adapter/state-redis zod
npm install ai chat @chat-adapter/slack @chat-adapter/state-redis zod
yarn add ai chat @chat-adapter/slack @chat-adapter/state-redis zod
bun add ai chat @chat-adapter/slack @chat-adapter/state-redis zod

Slack App Setup

Create a Slack app from a manifest:

  1. Go to api.slack.com/apps
  2. Click "Create New App" and choose "From a manifest"
  3. Select your workspace and paste the manifest below
  4. Install the app to your workspace
display_information:
  name: My Bot
  description: A bot built with the AI SDK and Chat SDK

features:
  agent_view:
    agent_description: A bot built with the AI SDK and Chat SDK
  bot_user:
    display_name: My Bot
    always_online: true

oauth_config:
  scopes:
    bot:
      - app_mentions:read
      - assistant:write
      - channels:history
      - channels:read
      - chat:write
      - groups:history
      - groups:read
      - im:history
      - im:read
      - mpim:history
      - mpim:read
      - reactions:read
      - reactions:write
      - users:read

settings:
  event_subscriptions:
    request_url: https://your-domain.com/api/webhooks/slack
    bot_events:
      - app_mention
      - message.channels
      - message.groups
      - message.im
      - message.mpim
      - member_joined_channel
      - app_home_opened
      - app_context_changed
      - agent_session_stopped
      - agent_session_title_changed
  interactivity:
    is_enabled: true
    request_url: https://your-domain.com/api/webhooks/slack

You will replace your-domain.com with your deployment URL after deploying.

Configure Environment Variables

Create a .env.local file in your project root:

SLACK_BOT_TOKEN=your_slack_bot_token
SLACK_SIGNING_SECRET=your_slack_signing_secret
REDIS_URL=your_redis_url
AI_GATEWAY_API_KEY=your_ai_gateway_api_key
  • SLACK_BOT_TOKEN: the Bot User OAuth Token from your Slack app's "OAuth & Permissions" page
  • SLACK_SIGNING_SECRET: the Signing Secret from your Slack app's "Basic Information" page
  • REDIS_URL: a Redis connection URL, such as one from a Redis integration on the Vercel Marketplace
  • AI_GATEWAY_API_KEY: your Vercel AI Gateway API key

The Slack adapter and the Redis state adapter read these variables automatically.

Create the Agent

Create the agent in lib/agent.ts. It uses the AI SDK's ToolLoopAgent with a weather tool, so it can call the tool and then answer with the result:

import { ToolLoopAgent, tool } from 'ai';
import { z } from 'zod';

export const agent = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  instructions: `You are a Slack bot assistant. Keep your responses concise and to the point.
  - Do not tag users.
  - Current date is: ${new Date().toISOString().split('T')[0]}`,
  tools: {
    getWeather: tool({
      description: 'Get the current weather at a location',
      inputSchema: z.object({
        latitude: z.number(),
        longitude: z.number(),
        city: z.string(),
      }),
      execute: async ({ latitude, longitude, city }) => {
        const response = await fetch(
          `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,weathercode,relativehumidity_2m&timezone=auto`,
        );

        const weatherData = await response.json();
        return {
          temperature: weatherData.current.temperature_2m,
          weatherCode: weatherData.current.weathercode,
          humidity: weatherData.current.relativehumidity_2m,
          city,
        };
      },
    }),
  },
});

ToolLoopAgent sends tool results back to the model automatically and keeps calling tools until the model writes a final answer (up to 20 steps by default). If a user asks "What's the weather in London?", the agent calls getWeather with London's coordinates and then answers using the result.

Create the Bot

Create the bot in lib/bot.ts. It connects the agent to Slack:

import { Chat, type Thread } from 'chat';
import { toAiMessages } from 'chat/ai';
import { createSlackAdapter } from '@chat-adapter/slack';
import { createRedisState } from '@chat-adapter/state-redis';
import { agent } from './agent';

export const bot = new Chat({
  userName: 'mybot',
  adapters: {
    // Match the manifest's `agent_view` (Slack's Agent messaging experience).
    slack: createSlackAdapter({ agentView: true }),
  },
  state: createRedisState(),
});

async function respond(thread: Thread) {
  await thread.startTyping();

  // Load recent messages and convert them to AI SDK messages.
  const { messages } = await bot.history.thread.list(thread.id, {
    limit: 20,
  });

  const result = await agent.stream({
    messages: await toAiMessages(messages),
    abortSignal: thread.signal,
  });

  // Stream the reply into the Slack thread.
  await thread.post(result.fullStream);
}

// A mention or a new direct message starts a conversation.
bot.onNewMention(async thread => {
  await thread.subscribe();
  await respond(thread);
});

// Later messages in a subscribed thread continue it.
bot.onSubscribedMessage(async thread => {
  await respond(thread);
});

Here's what each part does:

  • agentView: true tells the Slack adapter that the app uses Slack's Agent messaging experience, which the manifest enables with agent_view. In direct messages, each top-level message starts its own thread and the bot replies in that thread. Keep this option in sync with the manifest: without it, the adapter uses the older assistant_view thread mapping, and top-level direct messages fail to load their history.
  • onNewMention runs when someone mentions the bot in a thread it hasn't subscribed to. Direct messages are treated as mentions too. thread.subscribe() makes later messages in the thread go to onSubscribedMessage.
  • startTyping() shows Slack's typing indicator while the agent works.
  • bot.history.thread.list() loads the thread's recent messages, and toAiMessages converts them to ModelMessage[], with the bot's own messages as assistant messages.
  • thread.post(result.fullStream) streams the agent's reply into the thread. fullStream includes step boundaries, so Chat SDK can add paragraph breaks between the agent's steps. Chat SDK also converts the model's markdown to Slack formatting.
  • thread.signal is aborted when the user clicks Slack's stop button, which stops generation.

Create the Webhook Route

Create a route handler that passes Slack's events to the bot:

import { after } from 'next/server';
import { bot } from '@/lib/bot';

export async function POST(request: Request): Promise<Response> {
  return bot.webhooks.slack(request, {
    waitUntil: task => after(() => task),
  });
}

Slack expects a response within three seconds. The route responds right away, and waitUntil keeps the function running until the agent finishes its reply.

Deploying the App

  1. Install the Vercel CLI
pnpm install -g vercel
  1. Deploy the app
vercel deploy
  1. Go to your project's settings on Vercel (Your project -> Settings -> Environment Variables) and add the variables from your .env.local file

Note

Make sure to redeploy your app after updating environment variables.

  1. Go to your app on api.slack.com/apps and open "App Manifest". Replace your-domain.com in both request_url fields with your deployment's domain, for example:
https://your-vercel-url.vercel.app/api/webhooks/slack

Finally, head to Slack and test the app by mentioning the bot in a channel or sending it a direct message.

Next Steps

You've built a Slack agent powered by the AI SDK! Here are some ways you could extend it:

  1. Give the agent tools to read the channel or react to messages with Chat SDK's AI SDK tools
  2. Run the same bot on Microsoft Teams, Discord, and other platforms by adding adapters
  3. Implement more tools like database queries or knowledge base searches
  4. Post rich messages with cards and handle button clicks with actions

For a framework-managed alternative with durable threaded sessions, typing indicators, approval buttons, and multichannel support, see eve's Slack channel.