Module 4.4
Channel Integration
What Is a Channel?
A channel is the messaging platform your agent uses as its voice. OpenClaw doesn't have its own chat interface. It doesn't want one. Instead, it plugs into the apps you already live in — WhatsApp, Telegram, Discord, Slack, Signal — and talks to you there.
This is one of OpenClaw's sharpest design decisions. Every other AI assistant makes you go to it. OpenClaw comes to you. Your phone already has WhatsApp. Your team already has Slack. Add OpenClaw and your AI assistant is now a contact in your existing address book, not another app you have to remember to open.
The Gateway holds open persistent connections to every channel you configure. When you send a message on Telegram, it arrives at the Gateway, gets routed to the right agent, gets processed, and a response comes back — all inside the Telegram UI. To anyone watching, it looks like you're just texting someone.
Real-World Use Cases
- Telegram — most power users start here. Simple setup, good media support, reliable API. Your main personal assistant channel.
- WhatsApp — broad adoption. Good for assistants you share with family or clients who won't install Telegram.
- Discord — developer-first. Run the agent in a private server, get channel-specific routing, use it for project work.
- Slack — team context. The agent can read and respond in channels, participate in threads, coordinate with colleagues.
- Signal — privacy-focused. If you want end-to-end encryption for sensitive conversations with your agent.
- iMessage (via BlueBubbles) — macOS-only bridge. Your agent as an iMessage contact.
Multiple channels can run simultaneously. You can have Telegram for personal, WhatsApp for family, and Slack for work — all routing to the same (or different) agents, all from one Gateway.
Key Terms
Channel adapter — the code inside OpenClaw that connects to a specific messaging platform's API. Each platform has its own adapter. They all speak the same internal language to the Gateway; the adapter handles the platform-specific translation.
DM policy — the rule that governs who can start a direct message conversation with your agent. The most important access control you'll configure.
Pairing code — a short verification code that an unknown sender must provide to start chatting with your agent. Expires after 1 hour. This is how OpenClaw prevents random people from talking to your assistant.
Allowlist — an explicit list of user IDs permitted to interact with the agent. Nobody outside the list gets a response.
Long polling — Telegram's default method for receiving updates. OpenClaw keeps an open connection to Telegram's servers, and Telegram pushes messages down that connection when they arrive.
Webhook — an alternative to long polling. You give Telegram a URL; Telegram POSTs messages to it directly. Lower latency, but requires your Gateway to be publicly reachable via HTTPS.
How Channels Are Structured in Config
Every channel follows the same pattern in openclaw.json:
{
channels: {
<channel-name>: {
enabled: true,
// Authentication (bot token, QR scan, OAuth — varies by platform)
// Access control (dmPolicy, groups, allowlists)
// Platform-specific options
}
}
}You can enable as many channels as you want. They all run in parallel off the same Gateway. Messages from each are routed independently.
Setting Up Telegram (Start Here)
Telegram is the easiest channel to set up and the one most OpenClaw users start with. No QR scanning. No OAuth flows. Just a bot token and you're done.
Step 1: Create a bot via BotFather.
Open Telegram. Search for @BotFather. Send /newbot. Follow the prompts — give it a name, give it a username (must end in bot). BotFather hands you a token that looks like 123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ.
That token is your bot's identity. Treat it like a password.
Step 2: Add to config.
{
channels: {
telegram: {
enabled: true,
botToken: "${TELEGRAM_BOT_TOKEN}",
dmPolicy: "pairing",
groups: {
"*": { requireMention: true }
}
}
}
}Add TELEGRAM_BOT_TOKEN=123456789:ABCdef... to ~/.openclaw/.env.
Step 3: Start the Gateway and approve yourself.
openclaw gatewayNow open Telegram and send your bot a message — anything. You'll get a pairing code back. Approve it:
openclaw pairing list telegram # see pending codes
openclaw pairing approve telegram <CODE>You're connected. Send the bot another message — this time it responds.
Step 4 (optional): Webhook instead of long polling.
For production, webhooks are more reliable. They require a publicly reachable HTTPS URL — which means either a VPS with a domain, or Tailscale Serve.
{
channels: {
telegram: {
webhookUrl: "https://yourserver.example.com",
webhookSecret: "${TELEGRAM_WEBHOOK_SECRET}"
}
}
}Both webhookUrl and webhookSecret must be set together or neither. Long polling is fine for personal use. Switch to webhooks when you need lower latency or are running the agent for others.
Setting Up WhatsApp
WhatsApp uses QR-code authentication — it links an instance to your phone number the same way WhatsApp Web does.
Step 1: Add to config.
{
channels: {
whatsapp: {
enabled: true,
dmPolicy: "pairing",
groups: {
"*": { requireMention: true }
}
}
}
}Step 2: Scan the QR code.
Start the Gateway. OpenClaw will print a QR code in your terminal (or show it in the Control UI). Open WhatsApp on your phone → Settings → Linked Devices → Link a Device. Scan the QR code.
Your WhatsApp account is now linked. The agent can send and receive as you.
WhatsApp credentials are stored at ~/.openclaw/credentials/whatsapp/<accountId>/creds.json. This file is tied to your phone number. Don't delete it — re-linking requires another QR scan.
Important: WhatsApp's terms of service technically prohibit automated bots on personal accounts. Using it for personal automation (your own assistant) is low risk. Using it to message large numbers of people would be a different story. Know the distinction.
Setting Up Discord
Discord uses a bot token, similar to Telegram, but the setup involves their developer portal.
Step 1: Create a bot application.
Go to discord.com/developers/applications. Create a new application. Under the "Bot" tab, create a bot and copy the token.
Step 2: Set bot permissions.
In the OAuth2 → URL Generator, select scopes: bot. Select permissions: Send Messages, Read Message History, View Channels. Minimum needed for basic function. Copy the generated URL and use it to invite the bot to your server.
Step 3: Add to config.
{
channels: {
discord: {
enabled: true,
token: "${DISCORD_BOT_TOKEN}",
dmPolicy: "allowlist",
allowFrom: ["YOUR_DISCORD_USER_ID"]
}
}
}Discord user IDs are 18-digit numbers. To find yours: in Discord, enable Developer Mode (Settings → Advanced), then right-click your username → Copy User ID.
Setting Up iMessage (macOS Only, via BlueBubbles)
iMessage doesn't have an official bot API. OpenClaw reaches it through BlueBubbles — an open-source project that runs a server on your Mac and exposes iMessage over HTTP.
Requirements:
- A Mac with iMessage signed in (the same machine, or a separate always-on Mac)
- BlueBubbles server installed and running
- OpenClaw connected to the BlueBubbles endpoint
This is the most complex channel setup. It's worth it if iMessage is your primary channel (Apple ecosystem household, clients on iPhone). Skip it if you can use Telegram instead — same result, much less setup.
Access Control: Who Gets to Talk to Your Agent
Every channel exposes your agent to potential senders. Without access control, anyone who finds your bot's username can send it messages — and those messages become agent inputs with whatever tools you've enabled.
This is not theoretical. Telegram bots are publicly searchable. Discord bots can be invited to any server. WhatsApp bots are linked to a real phone number. You need to control who gets through.
DM Policy is the first gate. Set it on each channel:
{
channels: {
telegram: {
dmPolicy: "pairing" // or "allowlist", "open", "disabled"
}
}
}Four options:
"pairing" (recommended default) — an unknown sender gets a pairing code. They must send it back within 1 hour to start chatting. Maximum 3 codes pending at once. Good balance of openness and control — you can approve new people without pre-configuring them.
"allowlist" — only explicitly listed user IDs can DM the agent. Anyone else is silently ignored. Use this for a private personal assistant where you never want unexpected senders. You'll need to look up and add your own user ID.
"open" — anyone can message it. Never use this for an agent with tool access. Only appropriate for a fully sandboxed read-only public bot.
"disabled" — ignore all inbound DMs entirely. The agent only runs via cron/heartbeat — nobody can message it.
Group policy is the second gate. In any group chat, require the agent to be explicitly mentioned before it responds:
{
channels: {
telegram: {
groups: {
"*": { requireMention: true }
}
}
}
}Without requireMention: true, the agent tries to respond to every message in the group. It'll try to answer conversations it wasn't part of, burn tokens, and frustrate everyone. Always enable mention gating in groups.
Allowlists use numeric IDs, not usernames. Every platform assigns users a permanent numeric ID. Usernames change; IDs don't. OpenClaw's allowlists store IDs. If you added an old @username entry and it stopped working after the person changed their handle, that's why. Run openclaw doctor --fix to convert legacy username entries to IDs.
Multiple Channels, Multiple Agents: Routing
When you have multiple channels and multiple agents, you need to control which messages go to which agent. This is done via bindings — routing rules that match inbound messages to a specific agent.
The simplest version: route entire channels to different agents.
{
agents: {
list: [
{
id: "work",
bindings: [
{ channel: "slack" },
{ channel: "discord" }
]
},
{
id: "personal",
bindings: [
{ channel: "telegram" },
{ channel: "whatsapp" }
]
}
]
}
}Work conversations (Slack, Discord) go to the work agent. Personal conversations (Telegram, WhatsApp) go to the personal agent. They never see each other's messages. Their context stays separate.
You can go finer-grained: route a specific Telegram group to a specific agent, while regular DMs go to the default. Or route messages from a specific person to a specific agent. Bindings evaluate most-specific first — peer match beats channel match beats default.
Session Isolation: Keeping Contexts Separate
By default, all DMs — from any channel, from any sender — land in the same main session. The agent sees everything in one big context window.
For a single-user personal assistant, this is fine. You're the only sender; you want continuity.
For anything involving multiple senders, it's a problem. You don't want the agent mixing up context from two different people. You don't want a message from your client contaminating your personal conversation thread.
Set session scope to isolate contexts:
{
session: {
dmScope: "per-channel-peer" // one context per (channel, sender) pair
}
}Options:
"main" — default. All DMs share one context. Good for single-user setups.
"per-channel-peer" — separate context per channel and sender. Telegram message from Person A and Telegram message from Person B get different contexts. WhatsApp gets its own context too.
"per-account-channel-peer" — even finer: also separates by account when you have multiple accounts on the same platform.
The right choice depends on how many people interact with your agent. For a fully private personal assistant: "main". For an agent with multiple users or channels: "per-channel-peer".
Gotchas
Telegram Privacy Mode blocks group messages. By default, Telegram bots only see group messages that start with /. Your agent won't respond to normal conversation. Two fixes: either disable Privacy Mode (in BotFather: /setprivacy, set to Disabled, then remove and re-add the bot to the group) or make the bot an admin. After changing Privacy Mode, you must remove the bot from the group and re-add it — the change only applies to new sessions.
Group allowlisting catches people off guard. If you add any entry to channels.telegram.groups in your config, OpenClaw switches to explicit allowlisting mode — only groups that appear in the config will receive responses. If you add one group and forget to add "*" as a wildcard for others, all other groups go silent. Either list every group you want active, or include "*" to allow all.
WhatsApp re-linking after credential loss. If you delete ~/.openclaw/credentials/whatsapp/ or move to a new machine, you lose the WhatsApp session and must re-link via QR scan. This is unavoidable — the credential file is the session. Back it up the same way you'd back up an SSH key.
Discord needs the right intents enabled. For the bot to read message content in servers (not just slash commands), you must enable the "Message Content Intent" in the Discord Developer Portal under your bot's settings. Without it, the bot sees that messages exist but can't read their content. Symptoms: bot appears online, receives events, but never responds to regular messages.
Long polling and webhook conflict. You can't run both simultaneously. If you configure webhookUrl, OpenClaw switches to webhook mode and stops polling. If your webhook endpoint becomes unreachable (server down, DNS issues), messages stack up on Telegram's side until you either fix the endpoint or remove the webhook config and fall back to polling.
Pairing codes expire in 1 hour. If you configure a new channel, message the bot, get a code, and then forget to approve it for over an hour — the code expires and you have to start over. The bot will generate a new code on the next message.
Sources
- Telegram Channel Docs - OpenClaw
- OpenClaw Channels: Connect WhatsApp, Telegram & 20+ Apps
- OpenClaw WhatsApp Integration Guide
- Getting Started with OpenClaw and WhatsApp (MarkTechPost)