Skip to content
Slack Bot Agent: Building an AI Assistant for Team Communication
Learn Agentic AI13 min read15 views

Slack Bot Agent: Building an AI Assistant for Team Communication

Build a production-ready Slack bot agent using the Slack SDK that listens to events, handles slash commands, responds with interactive messages, and integrates LLM-powered reasoning for team support.

Why Slack Is the Perfect Home for AI Agents

Slack is where teams coordinate work. When an AI agent lives inside Slack, it eliminates context-switching. Instead of opening a separate tool, team members ask the agent directly in the channel where the conversation is already happening. The agent can answer questions about internal docs, summarize threads, create tickets, and route requests to the right people.

In this guide, we will build a Slack bot agent using Python's slack_bolt framework. The agent handles events, slash commands, and interactive messages while delegating complex reasoning to an LLM.

Setting Up the Slack App

Before writing code, create a Slack app at api.slack.com/apps. Enable Socket Mode for local development, add the chat:write, app_mentions:read, commands, and im:history scopes, and subscribe to the app_mention and message.im events.

flowchart LR
    INPUT(["User intent"])
    PARSE["Parse plus<br/>classify"]
    PLAN["Plan and tool<br/>selection"]
    AGENT["Agent loop<br/>LLM plus tools"]
    GUARD{"Guardrails<br/>and policy"}
    EXEC["Execute and<br/>verify result"]
    OBS[("Trace and metrics")]
    OUT(["Outcome plus<br/>next action"])
    INPUT --> PARSE --> PLAN --> AGENT --> GUARD
    GUARD -->|Pass| EXEC --> OUT
    GUARD -->|Fail| AGENT
    AGENT --> OBS
    style AGENT fill:#4f46e5,stroke:#4338ca,color:#fff
    style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
    style OBS fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
    style OUT fill:#059669,stroke:#047857,color:#fff

Install dependencies:

Hear it before you finish reading

Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.

Try Live Demo →
# pip install slack-bolt openai

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import os

app = App(token=os.environ["SLACK_BOT_TOKEN"])

Handling App Mentions

When someone mentions the bot in a channel, the agent processes the message and responds with LLM-generated content:

from openai import OpenAI

llm = OpenAI()

SYSTEM_PROMPT = (
    "You are a helpful team assistant in Slack. "
    "Answer questions concisely. Use bullet points for lists. "
    "If you do not know the answer, say so clearly."
)

def ask_llm(question: str, context: str = "") -> str:
    """Send a question to the LLM with optional context."""
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if context:
        messages.append({"role": "user", "content": f"Context:\n{context}"})
    messages.append({"role": "user", "content": question})

    response = llm.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        temperature=0.3,
        max_tokens=500,
    )
    return response.choices[0].message.content

@app.event("app_mention")
def handle_mention(event, say, client):
    """Respond to @bot mentions in channels."""
    user_text = event["text"]
    thread_ts = event.get("thread_ts", event["ts"])

    # Fetch thread context if replying in a thread
    context = ""
    if event.get("thread_ts"):
        result = client.conversations_replies(
            channel=event["channel"],
            ts=event["thread_ts"],
            limit=10,
        )
        context = "\n".join(
            m["text"] for m in result["messages"][:-1]  # Exclude current message
        )

    response = ask_llm(user_text, context)
    say(text=response, thread_ts=thread_ts)

The agent fetches thread history for context when mentioned inside a thread. This gives the LLM the full conversation to work with rather than just the latest message.

Implementing Slash Commands

Slash commands provide structured entry points for specific actions. Here we create a /ask command that accepts a question and a /summarize command that summarizes the current channel's recent messages:

@app.command("/ask")
def handle_ask(ack, command, say):
    """Handle the /ask slash command."""
    ack()  # Acknowledge within 3 seconds
    question = command["text"]
    if not question.strip():
        say("Usage: `/ask <your question>`", ephemeral=True)
        return
    answer = ask_llm(question)
    say(f"*Q:* {question}\n\n{answer}")

@app.command("/summarize")
def handle_summarize(ack, command, client, say):
    """Summarize recent channel messages."""
    ack()
    channel = command["channel_id"]
    result = client.conversations_history(channel=channel, limit=50)
    messages = [m["text"] for m in result["messages"] if m.get("text")]
    combined = "\n".join(messages[:50])

    summary = ask_llm(
        "Summarize the following Slack messages into 3-5 bullet points. "
        "Focus on decisions, action items, and key topics.",
        context=combined,
    )
    say(f"*Channel Summary (last 50 messages):*\n\n{summary}")

Always call ack() immediately when handling slash commands. Slack requires acknowledgment within three seconds or it shows an error to the user.

Interactive Messages with Buttons

Interactive messages let users take actions directly from the bot's response. Here we add approval buttons to a request workflow:

@app.command("/request")
def handle_request(ack, command, client):
    """Create an approval request with interactive buttons."""
    ack()
    request_text = command["text"]
    requester = command["user_id"]

    client.chat_postMessage(
        channel=os.environ["APPROVAL_CHANNEL"],
        text=f"New request from <@{requester}>",
        blocks=[
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": f"*New Request from <@{requester}>:*\n{request_text}",
                },
            },
            {
                "type": "actions",
                "elements": [
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text": "Approve"},
                        "style": "primary",
                        "action_id": "approve_request",
                        "value": f"{requester}|{request_text}",
                    },
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text": "Deny"},
                        "style": "danger",
                        "action_id": "deny_request",
                        "value": f"{requester}|{request_text}",
                    },
                ],
            },
        ],
    )

@app.action("approve_request")
def handle_approve(ack, body, client):
    """Handle approval button click."""
    ack()
    requester, request_text = body["actions"][0]["value"].split("|", 1)
    approver = body["user"]["id"]
    client.chat_postMessage(
        channel=requester,
        text=f"Your request was *approved* by <@{approver}>: {request_text}",
    )

Running the Agent

Start the bot with Socket Mode for development:

Still reading? Stop comparing — try CallSphere live.

CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.

if __name__ == "__main__":
    handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
    print("Slack bot agent is running...")
    handler.start()

For production, switch to HTTP mode behind a reverse proxy with proper SSL termination. Use a process manager like systemd or deploy as a container.

FAQ

How do I handle rate limits from the Slack API?

The slack_bolt framework includes built-in rate limit handling that automatically retries requests with appropriate backoff. For high-volume bots, use WebClient with retry_handlers configured and batch operations where possible.

Can the bot maintain conversation history across messages?

Store conversation context in a database or Redis keyed by channel ID and thread timestamp. Before each LLM call, retrieve the last N messages from your store to include as context. This gives the agent memory without relying solely on Slack API calls.

How do I restrict the bot to certain channels?

Check event["channel"] against an allowlist of channel IDs in your event handlers. Return early without processing if the channel is not in the list. You can also use Slack's app-level channel restrictions in the app configuration.


#SlackBot #AIAgents #SlackSDK #WorkflowAutomation #Python #ChatOps #AgenticAI #LearnAI #AIEngineering

Share

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like

AI Agents

Personal AI Assistant: How to Pick One for Business in 2026

A founder's guide to the personal AI assistant market: best AI assistant apps, business-grade options, and how CallSphere's voice agent fits in.

AI Agents

Free AI Agents in 2026: When Free Wins and When It Costs You

A founder's guide to free AI agents, low-code AI agent builders, and how to know when you should pay for a real platform like CallSphere.

Agentic AI

Graphiti: How Temporal Knowledge Graphs Give AI Voice Agents Persistent Memory (2026 Guide)

Graphiti is the open-source temporal knowledge graph for AI agents in 2026. Learn how bi-temporal memory beats vector RAG for voice agents and long-running LLMs.

AI Agents

Chatbot App vs ChatGPT: What's the Difference, and Which Do I Need?

Chatbot app vs ChatGPT in 2026: a founder's clear take on the difference, when to use which, and how a real AI chatbot app development works.

HVAC

Building an HVAC After-Hours Emergency Escalation System: A Complete Engineering Guide

How we built a fault-tolerant HVAC emergency triage and tech-dispatch platform on Kubernetes — three-tier CQRS, 11 micro-agents on the OpenAI Agents SDK + LangGraph, NATS JetStream, DTMF/SMS/WebSocket acceptance, circuit breakers, and an evaluation pipeline that catches regressions before they wake a tech at 3 AM.

Enterprise AI

OpenAI Frontier vs Anthropic Managed Agents: 2026 Comparison

Head-to-head: OpenAI Frontier and Anthropic's managed agent stack — strengths, fit, and what each means for enterprise AI voice and chat deployment.