AI Slack Integration: Building Enterprise AI Agents for Slack

TL;DR — AI Slack integration embeds AI agents into Slack workspaces for natural conversation, tool use, and action execution. Slack Developer Docs: "Agents are autonomous, goal-oriented AI apps that can reason, use tools, and maintain context across conversations in Slack. They go beyond simple Q&A bots by planning actions, calling external systems, and iterating on results." MoClaw: "A Slack integration in 2026 is not a slash command that posts a stub answer." CallSphere: "The Slack Bolt SDK for Python provides a clean abstraction over Slack's Events API, slash commands, interactive components, and Socket Mode." Key capabilities: app mentions (@ai-agent), slash commands (/ask-ai), thread replies (context-aware), interactive messages (approval buttons), event subscriptions (channel events), file sharing (document analysis). Slack Agentforce: "Powered by relevant conversations in Slack and your trusted enterprise data, Agentforce will suggest and take action right in the flow of work." Integrate with action approval, event automation, Nango integrations, and company knowledge.

Slack's developer documentation defines the new paradigm: "Agents are autonomous, goal-oriented AI apps that can reason, use tools, and maintain context across conversations in Slack. They go beyond simple Q&A bots by planning actions, calling external systems, and iterating on results without constant human intervention."

MoClaw's 2026 guide notes the evolution: "A Slack integration in 2026 is not a slash command that posts a stub answer. If a channel has both an AI agent and a human expert, the agent should know when to defer."

AI Slack Integration Architecture

flowchart TD subgraph Slack["Slack Workspace"] Channel["Channel
#engineering"] DM["Direct Message"] Thread["Thread"] Slash["Slash Command
/ask-ai"] Mention["App Mention
@ai-agent"] File["File Upload"] end subgraph Bolt["Slack Bolt SDK"] Events["Event Handler
(app_mention, message)"] Commands["Command Handler
(/ask-ai, /summarize)"] Interactive["Interactive Handler
(button clicks, menus)"] Files["File Handler
(file_shared)"] end subgraph AI["AI Platform"] Router["Query Router
(intent detection)"] RAG["RAG Pipeline
(knowledge retrieval)"] LLM["LLM Inference
(response generation)"] Memory["Session Memory
(thread context)"] Tools["Tool Registry
(external actions)"] end subgraph Actions["Agent Actions"] Reply["Post Reply
(in thread)"] Approve["Approval Workflow
(interactive buttons)"] Search["Search KB
(company knowledge)"] Notify["Notify Channel
(event-triggered)"] Summary["Summarize Thread
(context compression)"] end subgraph Governance["Governance"] RBAC["RBAC Check
(user permissions)"] Audit["Audit Log
(all actions)"] Policy["Policy Engine
(action approval)"] end Channel --> Events DM --> Events Thread --> Events Slash --> Commands Mention --> Events File --> Files Events --> Router Commands --> Router Interactive --> Router Files --> Router Router --> RAG RAG --> LLM LLM --> Memory LLM --> Tools LLM --> RBAC RBAC --> Policy Policy --> Audit LLM --> Reply Policy --> Approve RAG --> Search LLM --> Notify LLM --> Summary

Slack AI Agent Capabilities

Capability Trigger Implementation Use Case
App mention @ai-agent in channel Events API → app_mention Q&A, code help, lookups
Slash command /ask-ai Command handler Direct queries, summaries
Thread reply Reply in thread Thread_ts context tracking Follow-up questions, deep dives
Interactive message Button click Block Kit + interactive payload Approval workflows, model selection
File analysis File shared in channel file_shared event → download Document Q&A, code review
Channel monitoring New message in channel message event → analyze Triage, summarization, alerts
Reaction Emoji reaction reaction_added event Quick feedback, acknowledge
Scheduled summary Cron job Scheduled message via API Daily digests, thread summaries

Slack API Scopes

Scope Permission Required For
chat:write Send messages All agent responses
app_mentions:read Detect @mentions App mention trigger
channels:history Read channel messages Context, monitoring
groups:history Read private channels Private channel context
im:history Read DMs DM-based interactions
files:read Access shared files File analysis
files:write Upload files Generated reports, charts
reactions:write Add emoji reactions Acknowledge, status
users:read Get user info Personalization, RBAC
channels:join Join channels On invitation
pins:write Pin messages Important responses
chat:write.public Send to non-joined channels Cross-channel responses

Implementation

from slack_bolt import App as SlackApp
from slack_bolt.adapter.fastapi import SlackRequestHandler
from datetime import datetime, timezone

# Initialize Slack Bolt app
slack_app = SlackApp(
    token=os.environ["SLACK_BOT_TOKEN"],
    signing_secret=os.environ["SLACK_SIGNING_SECRET"],
)

# Initialize AI platform
ai_platform = AIPlatform(config)
audit = AuditLogger(db, master_key)


@slack_app.event("app_mention")
async def handle_mention(event, say, client):
    """Handle @ai-agent mentions in channels."""
    user_id = event["user"]
    channel_id = event["channel"]
    thread_ts = event.get("thread_ts", event["ts"])
    text = event["text"]

    # Extract query (remove bot mention)
    query = text.split(">", 1)[1].strip() if ">" in text else text

    # 1. Verify user has access (RBAC)
    user = await ai_platform.get_user_by_slack_id(user_id)
    if not user:
        await say(thread_ts=thread_ts, text=(
            "I don't recognize your Slack account. "
            "Please link your account in the dashboard."
        ))
        return

    # 2. Check rate limits
    if not await ai_platform.check_rate_limit(user.tenant_id):
        await say(thread_ts=thread_ts, text=(
            "Rate limit reached. Please try again in a minute."
        ))
        return

    # 3. Get conversation context from thread
    thread_history = await get_thread_history(client, channel_id, thread_ts)

    # 4. Route through RAG pipeline
    response = await ai_platform.query(
        tenant_id=user.tenant_id,
        user_id=user.id,
        query=query,
        context=thread_history,
        channel=channel_id,
    )

    # 5. Post response in thread
    await say(thread_ts=thread_ts, text=response.text)

    # 6. Audit log
    await audit.log(
        tenant_id=user.tenant_id,
        user_id=user.id,
        action="slack_mention_query",
        entity_type="slack_message",
        entity_id=event["ts"],
        after={"query": query, "response_length": len(response.text)},
    )


@slack_app.command("/ask-ai")
async def handle_ask_ai(ack, command, say):
    """Handle /ask-ai slash command."""
    await ack()  # Acknowledge within 3 seconds

    query = command["text"]
    user_id = command["user_id"]
    channel_id = command["channel_id"]

    user = await ai_platform.get_user_by_slack_id(user_id)
    if not user:
        await say("Please link your Slack account in the dashboard.")
        return

    # Show typing indicator
    response = await ai_platform.query(
        tenant_id=user.tenant_id,
        user_id=user.id,
        query=query,
        channel=channel_id,
    )

    await say(text=response.text)


@slack_app.command("/summarize")
async def handle_summarize(ack, command, say, client):
    """Summarize the current channel's recent messages."""
    await ack()

    channel_id = command["channel_id"]
    user_id = command["user_id"]

    # Fetch recent messages (last 50)
    result = await client.conversations_history(
        channel=channel_id, limit=50
    )
    messages = result["messages"]

    # Build conversation text for summarization
    conversation = []
    for msg in reversed(messages):
        if msg.get("type") == "message" and not msg.get("bot_id"):
            user_info = await client.users_info(user=msg["user"])
            name = user_info["user"]["real_name"]
            conversation.append(f"{name}: {msg['text']}")

    summary = await ai_platform.summarize(
        tenant_id=user.tenant_id,
        user_id=user.id,
        conversation="\n".join(conversation),
    )

    await say(text=f"*Channel Summary:*\n{summary}")


@slack_app.action("approve_action")
async def handle_approve(ack, body, say, client):
    """Handle approval button clicks."""
    await ack()

    user_id = body["user"]["id"]
    action_value = body["actions"][0]["value"]  # action_id from button

    # Verify user has approval authority
    user = await ai_platform.get_user_by_slack_id(user_id)
    approval = await ai_platform.get_pending_approval(action_value)

    if not await ai_platform.check_permission(
        user.tenant_id, user.id, Permission.AGENTS_OPERATE
    ):
        await say(text="You don't have permission to approve actions.")
        return

    # Execute the approved action
    result = await ai_platform.execute_approved_action(
        approval_id=action_value,
        approved_by=user.id,
    )

    # Update the original message
    await client.chat_update(
        channel=body["channel"]["id"],
        ts=body["message"]["ts"],
        text=f"✅ Approved by <@{user_id}>. Result: {result.summary}",
    )

    await audit.log(
        tenant_id=user.tenant_id,
        user_id=user.id,
        action="slack_approval_granted",
        entity_type="agent_action",
        entity_id=action_value,
    )


@slack_app.event("file_shared")
async def handle_file_shared(event, say, client):
    """Handle file uploads for analysis."""
    file_id = event["file_id"]
    user_id = event["user_id"]
    channel_id = event["channel_id"]

    # Download file
    file_info = await client.files_info(file=file_id)
    file_url = file_info["file"]["url_private_download"]

    # Analyze file through AI platform
    analysis = await ai_platform.analyze_file(
        tenant_id=user.tenant_id,
        user_id=user.id,
        file_url=file_url,
        file_type=file_info["file"]["filetype"],
    )

    await say(
        thread_ts=event.get("ts"),
        text=f"*File Analysis:*\n{analysis.summary}\n\n"
             f"Key points: {analysis.key_points}",
    )

Approval Workflow with Block Kit

def build_approval_message(action: dict) -> dict:
    """Build a Slack Block Kit message for approval workflow."""
    return {
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": f"*Action Approval Request*\n\n"
                            f"*Action:* {action['description']}\n"
                            f"*Agent:* {action['agent_name']}\n"
                            f"*Risk Level:* {action['risk_level']}\n"
                            f"*Details:* {action['details']}",
                },
            },
            {
                "type": "actions",
                "elements": [
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text": "✅ Approve"},
                        "style": "primary",
                        "value": action["id"],
                        "action_id": "approve_action",
                    },
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text": "❌ Reject"},
                        "style": "danger",
                        "value": action["id"],
                        "action_id": "reject_action",
                    },
                ],
            },
        ],
    }

AI Slack Integration Checklist

  • [ ] Create Slack app at api.slack.com/apps with correct scopes
  • [ ] Configure bot token scopes: chat:write, app_mentions:read, channels:history
  • [ ] Configure event subscriptions: app_mention, message, file_shared
  • [ ] Set up request URL for event delivery (HTTPS required)
  • [ ] Implement Slack Bolt SDK (Python: slack_bolt, JS: @slack/bolt)
  • [ ] Handle app_mention events — extract query, route to RAG pipeline
  • [ ] Handle slash commands — /ask-ai, /summarize, /approve
  • [ ] Implement thread-based context tracking using thread_ts
  • [ ] Implement interactive messages with Block Kit (buttons, menus)
  • [ ] Handle file_shared events — download and analyze shared files
  • [ ] Implement channel monitoring — read channel history for context
  • [ ] Map Slack user_id to platform user_id for RBAC and personalization
  • [ ] Verify user permissions before executing agent actions
  • [ ] Implement rate limiting per user and per channel
  • [ ] Post responses in threads (don't clutter main channel)
  • [ ] Use typing indicator for long-running queries
  • [ ] Implement approval workflow with Block Kit buttons
  • [ ] Track approval state: pending, approved, rejected, expired
  • [ ] Set approval timeout (24 hours) — auto-reject if no response
  • [ ] Update original message after approval/rejection
  • [ ] Implement thread summarization for long conversations
  • [ ] Implement daily digest — scheduled summary of channel activity
  • [ ] Add emoji reactions for quick feedback (✅ for completed)
  • [ ] Support file upload analysis (PDFs, code, spreadsheets)
  • [ ] Use Socket Mode for development, HTTP endpoints for production
  • [ ] Implement retry logic for Slack API failures
  • [ ] Handle Slack rate limits (429 responses with Retry-After)
  • [ ] Implement message formatting with Block Kit (sections, dividers, context)
  • [ ] Use ephemeral messages for private responses (/ask-ai results)
  • [ ] Integrate with action approval policies
  • [ ] Integrate with event-triggered automation
  • [ ] Connect to company knowledge RAG pipeline
  • [ ] Log all Slack interactions in audit logs
  • [ ] Apply RBAC to Slack-triggered actions
  • [ ] Use Nango for Slack OAuth and connection management
  • [ ] Apply zero-trust architecture to Slack integration
  • [ ] Apply OWASP LLM Top 10 security controls
  • [ ] Set up platform monitoring for Slack bot health
  • [ ] Monitor: response latency, error rate, user adoption, active channels
  • [ ] Implement graceful error messages (never expose stack traces to users)
  • [ ] Consider multi-tenant Slack workspace isolation
  • [ ] Support multiple Slack workspaces per tenant
  • [ ] Test: mention in public channel, DM, thread reply, slash command
  • [ ] Test: approval workflow end-to-end (request → approve → execute)
  • [ ] Test: file analysis with various file types
  • [ ] Test: rate limiting and error handling
  • [ ] Document Slack commands and bot capabilities for users
  • [ ] Consider AI incident response for Slack bot failures

FAQ

What is AI Slack integration?

AI Slack integration embeds AI agents directly into Slack workspaces, enabling users to interact with AI through natural conversation in channels, DMs, and threads. Unlike simple Q&A bots, AI agents in Slack can reason, use tools, call external systems, and maintain context across conversations. Slack's developer docs define agents as "autonomous, goal-oriented AI apps that can reason, use tools, and maintain context across conversations in Slack." Key capabilities: (1) App mentions — users @mention the bot in any channel. (2) Slash commands — /ask-ai for direct queries. (3) Thread replies — agent responds in thread context. (4) Interactive messages — buttons, menus for agent actions. (5) Event subscriptions — agent reacts to channel events. (6) File sharing — agent can read and analyze shared files. Built with Slack Bolt SDK (Python or JavaScript) and Events API.

How do you build an AI agent for Slack?

Build an AI agent for Slack with: (1) Create a Slack app at api.slack.com/apps with bot token scopes (chat:write, app_mentions:read, channels:history, files:read). (2) Configure event subscriptions — subscribe to app_mention and message events. (3) Set up request URL — your server endpoint that receives Slack events. (4) Implement slash commands — /ask-ai, /summarize, /approve. (5) Use Slack Bolt SDK — Python (slack_bolt) or JavaScript (@slack/bolt) for clean abstraction over Events API, slash commands, and interactive components. (6) Connect to LLM — route user queries through your AI platform's RAG pipeline. (7) Maintain conversation context — use thread_ts to track conversation history. (8) Implement interactive messages — buttons for approval workflows, menus for model selection. (9) Handle file uploads — download and analyze shared files. (10) Deploy with Socket Mode for development or HTTP endpoints for production.

What Slack API scopes does an AI agent need?

Required Slack API scopes for an AI agent: (1) chat:write — send messages to channels and DMs. (2) app_mentions:read — detect when the bot is @mentioned. (3) channels:history — read channel messages for context. (4) groups:history — read private channel messages. (5) im:history — read DM messages. (6) files:read — access shared files for analysis. (7) files:write — upload generated files. (8) reactions:write — add emoji reactions (e.g., checkmark for completed tasks). (9) users:read — get user info for personalization. (10) channels:join — join channels on invitation. (11) pins:write — pin important agent responses. (12) chat:write.public — send messages to channels the bot isn't a member of (with permission). Use OAuth 2.0 with bot token (xoxb-). Never use user tokens (xoxp-) for agent actions.

How do you implement approval workflows in Slack?

Implement approval workflows in Slack with interactive messages: (1) Agent proposes an action — posts a message with a 'Approve' button and 'Reject' button. (2) User clicks 'Approve' — Slack sends an interactive payload to your server. (3) Server verifies the user has approval authority (RBAC check). (4) Server executes the action. (5) Agent posts result — updates the original message with outcome. (6) If rejected — agent logs the rejection and offers alternatives. Implementation: use Slack Block Kit for interactive messages with buttons, select menus, and date pickers. Track approval state in database (pending, approved, rejected, expired). Set timeout (e.g., 24 hours) — if no response, auto-reject and notify. Integrate with action approval policies — some actions require one approver, others require two. Log all approvals in audit logs.

How do you maintain conversation context in Slack AI agents?

Maintain conversation context in Slack AI agents with: (1) Thread-based context — use thread_ts to track conversation history within a Slack thread. Each reply in the thread includes previous messages as context. (2) Channel context — read recent channel messages (channels:history scope) to understand ongoing discussions. (3) User memory — store per-user preferences and past interactions in your platform's memory system. (4) Session management — map Slack user_id to platform user_id, maintain session state across channels. (5) Context window management — truncate old messages when context exceeds LLM's token limit. (6) Summarization — for long threads, summarize previous messages before adding to context. (7) Channel awareness — agent knows which channel it's in and adapts responses (e.g., #engineering vs #sales). (8) Multi-channel state — if a user interacts with the agent in multiple channels, maintain shared context. Use Redis for fast session state retrieval.


Want a self-hosted AI company brain that does all of this out of the box?
Book a demo →