Back to Blog
TutorialFebruary 2, 202615 min

Slack AI Chatbot: Enterprise Integration Guide

Add an AI assistant to your Slack workspace with the Bolt SDK. Thread support, slash commands, and enterprise features.

slackchatbotenterpriseboltai integration

Molted Team

Molted.cloud

Slack is where work happens. Adding an AI assistant directly in Slack means your team can get answers, generate content, and automate tasks without leaving their workflow. This guide covers building a Slack AI bot with the Bolt SDK and deploying it for your workspace.

Why Slack AI bots matter for teams

  • Context where you work - No switching to ChatGPT or Claude web
  • Team-wide access - Everyone can use it, not just those with AI subscriptions
  • Channel-specific assistants - Different bots for engineering, sales, support
  • Integration potential - Connect to your internal tools and data
  • Audit trail - All interactions logged in Slack

Create a Slack app

  1. Go to api.slack.com/apps
  2. Click "Create New App" → "From scratch"
  3. Name it and select your workspace

Configure OAuth scopes

Go to OAuth & Permissions → Scopes → Bot Token Scopes. Add:

  • app_mentions:read - Know when mentioned
  • chat:write - Send messages
  • im:history - Read DM history
  • im:read - Access DMs
  • im:write - Send DMs

Enable Socket Mode

Socket Mode lets you run the bot locally without a public URL. Go to Socket Mode → Enable. Generate an app-level token with connections:write scope.

Subscribe to events

Go to Event Subscriptions → Enable. Subscribe to bot events:

  • app_mention
  • message.im

Install to workspace

Go to Install App → Install to Workspace. Copy the Bot User OAuth Token.

Project setup with Bolt

mkdir slack-ai-bot
cd slack-ai-bot
npm init -y
npm install @slack/bolt @anthropic-ai/sdk dotenv

Create .env:

SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
ANTHROPIC_API_KEY=your-anthropic-key

Basic Slack AI bot

require('dotenv').config();
const { App } = require('@slack/bolt');
const Anthropic = require('@anthropic-ai/sdk');

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  appToken: process.env.SLACK_APP_TOKEN,
  socketMode: true,
});

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

// Store conversations per channel/DM
const conversations = new Map();

// Handle mentions in channels
app.event('app_mention', async ({ event, say }) => {
  const channelId = event.channel;
  const text = event.text.replace(/<@[A-Z0-9]+>/g, '').trim();

  if (!text) {
    await say('How can I help you?');
    return;
  }

  await handleMessage(channelId, text, say);
});

// Handle DMs
app.event('message', async ({ event, say }) => {
  // Only handle DMs, not channel messages
  if (event.channel_type !== 'im') return;
  // Ignore bot messages
  if (event.bot_id) return;

  const channelId = event.channel;
  const text = event.text;

  await handleMessage(channelId, text, say);
});

async function handleMessage(channelId, text, say) {
  // Get or create conversation
  if (!conversations.has(channelId)) {
    conversations.set(channelId, []);
  }
  const history = conversations.get(channelId);

  // Add user message
  history.push({ role: 'user', content: text });

  // Trim history
  if (history.length > 20) {
    history.splice(0, history.length - 20);
  }

  try {
    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 1024,
      system: `You are a helpful assistant in a Slack workspace.
Keep responses professional and concise.
Use Slack formatting: *bold*, _italic_, \`code\`, \`\`\`code blocks\`\`\`.`,
      messages: history,
    });

    const reply = response.content[0].text;
    history.push({ role: 'assistant', content: reply });

    await say(reply);
  } catch (error) {
    console.error('Error:', error);
    await say('Sorry, I encountered an error. Please try again.');
  }
}

(async () => {
  await app.start();
  console.log('Slack bot is running!');
})();

Enterprise-ready Slack AI

OpenClaw includes Slack integration with SSO and admin controls.

Start free trial

Thread support

Slack threads are essential for organized conversations:

app.event('app_mention', async ({ event, say, client }) => {
  const threadTs = event.thread_ts || event.ts;
  const channelId = event.channel;

  // Use thread ID for conversation context
  const contextId = `${channelId}-${threadTs}`;

  if (!conversations.has(contextId)) {
    conversations.set(contextId, []);
  }
  const history = conversations.get(contextId);

  const text = event.text.replace(/<@[A-Z0-9]+>/g, '').trim();
  history.push({ role: 'user', content: text });

  const response = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: history,
  });

  const reply = response.content[0].text;
  history.push({ role: 'assistant', content: reply });

  // Reply in thread
  await client.chat.postMessage({
    channel: channelId,
    thread_ts: threadTs,
    text: reply,
  });
});

Slash commands

Add slash commands for specific actions. In your Slack app settings, go to Slash Commands → Create New Command.

// /ask command for quick questions
app.command('/ask', async ({ command, ack, respond }) => {
  await ack();

  const question = command.text;

  if (!question) {
    await respond('Usage: /ask <your question>');
    return;
  }

  const response = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: [{ role: 'user', content: question }],
  });

  await respond({
    response_type: 'in_channel', // visible to everyone
    text: response.content[0].text,
  });
});

// /summarize command for channel summaries
app.command('/summarize', async ({ command, ack, respond, client }) => {
  await ack();

  // Get recent messages from channel
  const result = await client.conversations.history({
    channel: command.channel_id,
    limit: 50,
  });

  const messages = result.messages
    .filter(m => !m.bot_id)
    .map(m => m.text)
    .reverse()
    .join('\n');

  const response = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: [{
      role: 'user',
      content: `Summarize these Slack messages in bullet points:\n\n${messages}`,
    }],
  });

  await respond(response.content[0].text);
});

Interactive messages

app.event('app_mention', async ({ event, client }) => {
  await client.chat.postMessage({
    channel: event.channel,
    text: 'How can I help?',
    blocks: [
      {
        type: 'section',
        text: { type: 'mrkdwn', text: 'What would you like to do?' },
      },
      {
        type: 'actions',
        elements: [
          {
            type: 'button',
            text: { type: 'plain_text', text: 'Summarize channel' },
            action_id: 'summarize_channel',
          },
          {
            type: 'button',
            text: { type: 'plain_text', text: 'Generate report' },
            action_id: 'generate_report',
          },
        ],
      },
    ],
  });
});

app.action('summarize_channel', async ({ ack, body, client }) => {
  await ack();
  // ... summarization logic
});

Slack AI without the setup

Molted deploys OpenClaw with Slack ready. OAuth install, done.

Try free for 24 hours

Webhook deployment (production)

For production without Socket Mode:

const { App, ExpressReceiver } = require('@slack/bolt');

const receiver = new ExpressReceiver({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
});

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  receiver,
});

// Your event handlers...

(async () => {
  await app.start(process.env.PORT || 3000);
  console.log('Slack bot running on port 3000');
})();

Set the Request URL in Event Subscriptions to https://your-domain.com/slack/events.

Security best practices

  • Verify requests - Bolt does this automatically with signing secret
  • Limit permissions - Only request scopes you need
  • Rate limit users - Prevent API cost abuse
  • Audit logging - Log all AI interactions for compliance

OpenClaw for Slack

OpenClaw supports Slack via the Bolt SDK internally. Benefits over DIY:

  • OAuth flow handled - Users install via button click
  • Multi-workspace support - One deployment, many workspaces
  • Admin dashboard - See usage, manage access
  • Model switching - Change between Claude/GPT without code

Related guides

Free 24-hour trial

Slack AI for your team

OpenClaw on Molted. Install to Slack in one click. 24-hour free trial.

Start free trial

24-hour free trial · No credit card required · Cancel anytime

Ready to try OpenClaw?

Deploy your AI personal assistant in 60 seconds. No coding required.

Start free trial

24-hour free trial · No credit card required