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.
Molted Team
molted.cloud
Add an AI assistant to your Slack workspace with the Bolt SDK. Thread support, slash commands, and enterprise features.
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.
Go to OAuth & Permissions → Scopes → Bot Token Scopes. Add:
app_mentions:read - Know when mentionedchat:write - Send messagesim:history - Read DM historyim:read - Access DMsim:write - Send DMsSocket 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.
Go to Event Subscriptions → Enable. Subscribe to bot events:
app_mentionmessage.imGo to Install App → Install to Workspace. Copy the Bot User OAuth Token.
mkdir slack-ai-bot
cd slack-ai-bot
npm init -y
npm install @slack/bolt @anthropic-ai/sdk dotenvCreate .env:
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
ANTHROPIC_API_KEY=your-anthropic-keyrequire('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.
Coming soonSlack 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,
});
});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);
});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.
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.
OpenClaw supports Slack via the Bolt SDK internally. Benefits over DIY:
OpenClaw on Molted. Install to Slack in one click. 24-hour free trial.
24-hour free trial · no credit card · cancel anytime
Build an AI assistant for Microsoft Teams with Bot Framework. SSO, compliance, and admin controls for enterprise.
Honest comparison of free AI chatbots including ChatGPT, Claude, Gemini, Copilot, and self-hosted options. Limits and catches explained.
Run your personal AI assistant 24/7 on a Mac Mini. Complete setup guide for OpenClaw, formerly known as Clawdbot and MoltBot.
ENCORE DEBOUT ?