Claw Mart
← Back to Blog
March 21, 20268 min readClaw Mart Team

How to Connect OpenClaw to Telegram and Slack

How to Connect OpenClaw to Telegram and Slack

How to Connect OpenClaw to Telegram and Slack

Let's cut to it: you've built an AI agent, it works in your terminal, and now you want real humans to actually use it. That means putting it where people already are — Slack and Telegram.

Sounds straightforward, right? Except it's not. You've got Slack's Bolt framework, OAuth flows, Events API retries, and Block Kit on one side. On the other, Telegram's Bot API with its own webhooks, polling modes, and group chat quirks. Two completely different mental models, two sets of documentation, two codebases to maintain. Most people budget a weekend for this and end up burning two weeks debugging webhook deduplication at 1am.

I know because I've been there. And I know a lot of you have been there too, based on the sheer volume of "why is my Slack bot replying twice to everything" posts I've seen on Reddit.

OpenClaw exists specifically to make this problem go away. Instead of wiring up platform SDKs yourself, you configure one adapter layer and deploy your agent to both platforms simultaneously. The rest of this post is a step-by-step walkthrough of how to actually do it.

Why Most People Fail at This (And It's Not Their Fault)

Before we get into the how, let's acknowledge why this is genuinely hard without the right tooling.

The platform SDKs have completely different mental models. Slack uses a workspace-based OAuth installation flow with event subscriptions that send HTTP retries if you don't respond within 3 seconds. Telegram uses a simpler bot token model but has its own headaches with webhook vs. long-polling, group privacy modes, and inline keyboards. Trying to abstract over both yourself means building a mini-framework before you even touch your agent logic.

State management is a nightmare. Your agent needs to remember conversations per-channel in Slack, per-thread in Slack threads, per-user in Telegram DMs, and per-group in Telegram groups. Most tutorials use an in-memory dictionary, which dies on the first server restart. Congratulations, your bot now has amnesia.

Event deduplication will haunt you. Slack resends events if your server doesn't acknowledge within 3 seconds. If your agent takes 10 seconds to think (which it will), you'll get duplicate messages. Telegram webhooks can double-fire during network hiccups. Without proper handling, your agent replies twice, three times, or enters a loop that burns through your API budget faster than you can say "rate limit."

Latency kills trust. Users in a chat expect responses in under 5 seconds. AI agents routinely take 10-40 seconds, especially with tool use. Without typing indicators, "thinking" messages, or streaming, users assume the bot is broken and spam it with more messages — which compounds every problem above.

OpenClaw handles all of this out of the box. Let's set it up.

What You'll Need Before Starting

Here's your checklist:

  • Python 3.10+ installed
  • A Slack workspace where you can create apps (you need admin or permission to install apps)
  • A Telegram bot token from @BotFather
  • Redis or Postgres for persistent state (Redis is easiest to start; a free tier on Railway or Upstash works fine)
  • OpenClaw installed — and if you want to skip a lot of the initial configuration headaches, Felix's OpenClaw Starter Pack is the move. It bundles pre-configured templates, environment files, and deployment configs that would otherwise take you hours to piece together from docs and GitHub issues. More on this below.

Step 1: Install OpenClaw and Initialize Your Project

pip install openclaw
openclaw init my-agent
cd my-agent

This scaffolds a project structure:

my-agent/
ā”œā”€ā”€ agent.py          # Your agent logic
ā”œā”€ā”€ openclaw.yaml     # Platform configuration
ā”œā”€ā”€ .env.example      # Environment variables template
ā”œā”€ā”€ adapters/
│   ā”œā”€ā”€ slack.py      # Slack adapter (pre-configured)
│   └── telegram.py   # Telegram adapter (pre-configured)
ā”œā”€ā”€ memory/
│   └── config.py     # State/memory backend config
└── docker-compose.yml

The key insight here: your agent logic lives in one place (agent.py), and the platform-specific stuff is handled by the adapters and openclaw.yaml. You never write Slack Bolt code or python-telegram-bot code directly.

Step 2: Configure Your Platforms in openclaw.yaml

This is where OpenClaw earns its keep. Open openclaw.yaml:

platforms:
  slack:
    enabled: true
    signing_secret: ${SLACK_SIGNING_SECRET}
    bot_token: ${SLACK_BOT_TOKEN}
    app_token: ${SLACK_APP_TOKEN}  # For Socket Mode (dev) or omit for webhooks (prod)
    events:
      - message
      - app_mention
    deduplication: true
    retry_handling: auto
    ux:
      typing_indicator: true
      thinking_message: "🧠 Working on it..."
      stream_responses: true

  telegram:
    enabled: true
    bot_token: ${TELEGRAM_BOT_TOKEN}
    mode: webhook  # or 'polling' for local dev
    webhook_url: ${WEBHOOK_BASE_URL}/telegram/webhook
    allowed_updates:
      - message
      - callback_query
    group_privacy: false  # Set true if bot should only respond to commands in groups
    ux:
      typing_indicator: true
      thinking_message: "🧠 Thinking..."
      stream_responses: false  # Telegram doesn't support true streaming

memory:
  backend: redis  # Options: redis, postgres, sqlite (dev only)
  connection_url: ${REDIS_URL}
  strategy: per_thread  # Manages memory per Slack thread and Telegram chat automatically
  max_history: 50  # Messages to retain per conversation
  ttl: 86400  # Expire conversations after 24 hours of inactivity

guardrails:
  rate_limit:
    per_user: 20/minute
    per_channel: 60/minute
  loop_detection:
    enabled: true
    max_consecutive_agent_messages: 3
  input_sanitization: true
  max_input_length: 4000

Let me highlight what's happening here that would otherwise take you days to implement:

  • deduplication: true — OpenClaw tracks Slack event IDs and Telegram update IDs, silently dropping retries. No more double responses.
  • retry_handling: auto — Slack gets an immediate 200 OK response while the agent processes in the background. This alone fixes 80% of Slack webhook issues people encounter.
  • strategy: per_thread — Memory is automatically scoped. Slack thread A gets its own conversation history, Slack thread B gets its own, Telegram user DMs are isolated, Telegram group chats are isolated. All persisted in Redis.
  • loop_detection — If the agent fires more than 3 consecutive messages without user input, it stops. This is the guardrail that prevents the "$47 in one hour" horror stories.

Step 3: Write Your Agent Logic

Here's where you focus on what actually matters — your agent's behavior. OpenClaw works with LangGraph, CrewAI, or plain function-based agents. Here's a LangGraph example:

# agent.py
from openclaw import Agent, tool
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

@tool
def search_docs(query: str) -> str:
    """Search internal documentation for answers."""
    # Your retrieval logic here
    results = your_vector_store.similarity_search(query, k=3)
    return "\n".join([doc.page_content for doc in results])

@tool
def create_ticket(title: str, description: str, priority: str = "medium") -> str:
    """Create a support ticket."""
    # Your ticketing API logic here
    ticket_id = your_api.create_ticket(title=title, description=description, priority=priority)
    return f"āœ… Ticket created: #{ticket_id}"

agent = Agent(
    name="SupportBot",
    llm=llm,
    tools=[search_docs, create_ticket],
    system_prompt="""You are a helpful internal support agent. 
    Search documentation before answering questions. 
    If the user needs something you can't resolve, create a ticket.
    Be concise — this is a chat, not an essay.""",
)

That's your entire agent. Notice there's zero platform-specific code. No Slack Bolt decorators, no Telegram handler functions, no webhook parsing. OpenClaw's adapter layer handles the translation between platform events and your agent's input/output.

Step 4: Set Up Your Environment Variables

Copy .env.example to .env and fill it in:

# Slack (get these from api.slack.com/apps)
SLACK_SIGNING_SECRET=your_signing_secret
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token  # Only needed for Socket Mode

# Telegram (get from @BotFather)
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

# Memory
REDIS_URL=redis://localhost:6379/0

# LLM
OPENAI_API_KEY=sk-your-key

# Webhooks (production)
WEBHOOK_BASE_URL=https://your-domain.com

For the Slack app setup specifically, you need to:

  1. Go to api.slack.com/apps and create a new app
  2. Enable Socket Mode (for development) or set up Event Subscriptions with your webhook URL (for production)
  3. Subscribe to bot events: message.channels, message.groups, message.im, app_mention
  4. Add OAuth scopes: chat:write, channels:history, groups:history, im:history, reactions:read
  5. Install to your workspace and grab the bot token

For Telegram:

  1. Message @BotFather, create a new bot, grab the token
  2. If you want the bot to see all messages in groups (not just commands), disable privacy mode with /setprivacy → Disabled

If this setup matrix is making your eyes glaze over, this is exactly where Felix's OpenClaw Starter Pack saves serious time. It includes pre-filled configuration templates for both platforms, annotated .env files with every field explained, and a step-by-step Slack app manifest you can import directly instead of clicking through 15 settings screens. I wish I'd had it when I was first setting all this up.

Step 5: Run Locally

# Start Redis (if running locally)
docker run -d -p 6379:6379 redis:alpine

# Run your agent
openclaw dev

The dev command starts both adapters simultaneously. Slack connects via Socket Mode (no public URL needed), and Telegram uses long-polling. You'll see output like:

[OpenClaw] āœ“ Slack adapter connected (Socket Mode)
[OpenClaw] āœ“ Telegram adapter connected (polling)
[OpenClaw] āœ“ Redis memory backend connected
[OpenClaw] āœ“ Agent "SupportBot" ready on 2 platforms

Go message your bot in Slack and Telegram. Same agent, same tools, same memory strategy, two platforms. That's the whole point.

Step 6: Deploy to Production

Local dev is great, but you need this running 24/7. Here's the Docker Compose setup that comes with OpenClaw:

# docker-compose.yml
version: "3.8"
services:
  agent:
    build: .
    env_file: .env
    ports:
      - "3000:3000"
    depends_on:
      - redis
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  redis:
    image: redis:alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  redis_data:

For production, you switch from Socket Mode to webhooks for Slack and from polling to webhooks for Telegram. Update your openclaw.yaml:

platforms:
  slack:
    app_token: null  # Remove this to disable Socket Mode
  telegram:
    mode: webhook

Then run:

openclaw deploy  # Sets up Telegram webhook URL automatically
docker-compose up -d

OpenClaw handles Slack's URL verification challenge automatically when Slack first pings your endpoint. For Telegram, the deploy command calls the setWebhook API with your configured URL.

Where to host: Railway, Fly.io, and Google Cloud Run all work. OpenClaw ships with deployment configs for all three. The key requirement is a persistent server (not a pure serverless function) because you need the webhook endpoints running continuously. Railway is probably the lowest-friction option — railway up from your project directory and you're done.

Step 7: Monitor Everything

Once deployed, you need to know what's happening. OpenClaw includes built-in observability:

openclaw logs --tail 50

Every agent run logs:

{
  "timestamp": "2026-01-15T14:32:01Z",
  "platform": "slack",
  "channel": "C04ABCDEF",
  "thread_ts": "1705312321.000100",
  "user": "U04GHIJKL",
  "input": "How do I reset my password?",
  "output": "You can reset your password at settings.company.com/reset...",
  "tools_used": ["search_docs"],
  "tokens": {"input": 847, "output": 124},
  "cost_usd": 0.00023,
  "latency_ms": 3241,
  "status": "success"
}

Token usage, cost tracking, latency, which tools were called, which platform, which user — all automatically captured. When something breaks at 2am, you'll actually know why.

Common Gotchas and How OpenClaw Handles Them

"My bot responds to its own messages in Slack channels." OpenClaw automatically filters out bot messages by default. You don't need to add if message.bot_id: return anywhere.

"The bot is replying to every message in a busy Telegram group." Use group_privacy: true in your config, and the bot only responds to direct commands (/ask, etc.) or messages that @ mention it. You can also configure keyword triggers.

"Slack threads and channel messages are getting mixed up." The per_thread memory strategy handles this. Threaded conversations get their own memory context. Top-level channel messages get a separate context. No crossed wires.

"I hit Telegram's 4096 character message limit." OpenClaw automatically chunks long responses into multiple messages with a brief delay between them so they arrive in order.

"My agent costs too much in group chats." The rate limiter in the guardrails config caps usage per user and per channel. Combined with loop detection, your worst case is predictable and bounded.

Where to Go From Here

You've got a working agent on two platforms. Here's what to tackle next:

  1. Add buttons and interactive elements. OpenClaw supports Slack Block Kit buttons and Telegram inline keyboards through a unified actions API. Let users approve tickets, pick options, or trigger tools with a tap instead of typing.

  2. Add more tools. Your agent is only as useful as its tools. Connect it to your calendar, CRM, docs, database — whatever your team actually needs.

  3. Fine-tune your system prompt. The agent's personality and accuracy depend heavily on the system prompt. Iterate on it based on real conversations from your logs.

  4. Set up per-channel configurations. OpenClaw lets you configure different tools and behaviors per Slack channel or Telegram group. Your #engineering channel might get code search tools while #sales gets CRM tools.

  5. Explore the community. OpenClaw is open source and the community is growing. The GitHub discussions and Discord are solid places to ask questions and share configs.

And seriously, if you haven't already, grab Felix's OpenClaw Starter Pack. It's the fastest path from "I want to do this" to "it's running in production." The pre-configured templates, deployment configs, and annotated environment files eliminate the exact configuration maze that trips up most people in their first few hours. Future you will be grateful.

Now stop reading and go ship the thing.

Claw Mart Daily

Get one AI agent tip every morning

Free daily tips to make your OpenClaw agent smarter. No spam, unsubscribe anytime.

More From the Blog