Connecting WhatsApp and Telegram to OpenClaw: A Practical Setup Guide
Connecting a channel is the moment OpenClaw stops being a local process and becomes an assistant. It’s also the moment you attach an autonomous agent to an account other humans can message — so the order you do things in matters.
This page covers the two channels most people start with. Telegram, because it’s the safest place to learn. WhatsApp, because it’s where most people actually live. Both have specific traps that are much easier to avoid than to undo.
Start With Telegram. Genuinely.
Even if WhatsApp is your goal, do Telegram first. The reasoning is practical, not ideological.
A Telegram bot is a separate identity. You create it through BotFather, it has its own username, and it has no relationship to your personal account. If you misconfigure it, delete the bot and start over — nobody notices. Nothing in your real message history is involved.
WhatsApp works differently. There is no first-class bot concept for personal use; you link OpenClaw as a companion device on a real account. That has consequences: the assistant sits inside an account with real conversations and real contacts, and mistakes are visible to people you know.
So: learn the pairing flow, the allowlist formats, and the mention rules on the channel where errors are cheap. Then apply what you learned where they aren’t.
Telegram Setup
1. Create the bot
Message @BotFather on Telegram and send /newbot. You’ll pick a display name and a username ending in bot. BotFather returns a token that looks like 123456789:AAH....
That token is a credential with full control of the bot. Anyone holding it can read every message sent to your bot and send messages as it. Treat it like a password — and if it ever appears in a screenshot, a paste, or a commit, revoke it with /revoke immediately.
Two settings worth changing while you’re in BotFather:
/setprivacy→ Disable — only if you want the bot to see all group messages rather than just ones that mention it. Leave privacy enabled unless you have a specific reason; it’s a useful extra layer on top of OpenClaw’s own mention gating./setdescription— cosmetic, but helpful if others will use it.
2. Find your numeric user ID
This is the step people skip, and then wonder why their allowlist doesn’t work. Telegram allowlists use numeric user IDs, not @usernames. Usernames can be changed and reassigned; IDs cannot.
Message @userinfobot and it replies with your ID — a number like 123456789.
3. Configure
{ channels: { telegram: { botToken: "123456789:AAH-your-token-here", dmPolicy: "pairing", allowFrom: ["tg:123456789"], groups: { "*": { requireMention: true } } } }}The Gateway hot-reloads this — no restart needed.
4. Test
Message your bot. If you’re in allowFrom, you get a reply. If you’re not, you get a pairing code, and nothing happens until you approve it:
openclaw pairing approve telegram 428913Telegram group chats
Add the bot to a group and it’s silent by default, because requireMention is on. That’s correct behaviour — a bot that responds to every message in an active group is intolerable within about an hour.
Per-group overrides let you loosen this where it makes sense:
{ channels: { telegram: { botToken: "123456789:AAH-...", dmPolicy: "pairing", allowFrom: ["tg:123456789"], groups: { "*": { requireMention: true }, "-1001234567890": { allowFrom: ["@admin"], requireMention: false } } } }}Group IDs are negative numbers starting -100. The Control UI shows them when a message arrives, which is far easier than hunting through API responses.
Only turn off requireMention in a quiet, purpose-built group. In a busy one you’ll regret it immediately, and your token bill will make the point for you.
Running multiple Telegram bots
Useful when you want a chatty personal assistant and a separate silent alerting bot:
{ channels: { telegram: { accounts: { default: { botToken: "123456:ABC..." }, alerts: { botToken: "987654:XYZ..." } } } }}WhatsApp Setup
Understand what you’re linking first
OpenClaw connects to WhatsApp as a linked companion device — the same mechanism as WhatsApp Web. Which means:
- It operates within a real WhatsApp account, with that account’s contacts and groups.
- The link shows up in Settings → Linked Devices on your phone, and can be revoked there at any time.
- Your phone needs to come online periodically for the link to stay healthy.
- Automating a personal account carries some risk of WhatsApp flagging unusual behaviour. High message volume to people who haven’t messaged you is the pattern that causes trouble.
Many people use a secondary number — a cheap SIM or a spare eSIM — specifically for this. It keeps the assistant away from your primary account entirely, and it’s the setup I’d recommend if you’re at all uncertain. The cost is that people have to message a different number to reach it.
1. Configure before linking
Do this in the right order. Set the policy first, then link the device. Linking first leaves a live connection running under whatever defaults existed.
{ channels: { whatsapp: { dmPolicy: "pairing", allowFrom: ["+15555550123"], groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"], groups: { "*": { requireMention: true } } } }}Phone numbers go in full international format with the + and country code. +15555550123, not 5555550123.
2. Link the device
Start the channel and OpenClaw presents a QR code — in the terminal, or more legibly in the Control UI at http://127.0.0.1:18789. On your phone: Settings → Linked Devices → Link a Device, and scan.
If the terminal QR renders as unreadable blocks, use the Control UI instead. This is a common source of pointless frustration.
3. Verify from a second account
Test from a different phone or a friend’s account, not from your own. Messaging yourself on WhatsApp doesn’t exercise the same inbound path and can produce a false sense that everything works.
WhatsApp group chats
Groups are where WhatsApp gets risky, because a group contains people who never agreed to talk to an AI agent.
groupPolicy: "allowlist" is the default and should stay that way. Combined with requireMention, the agent is silent in every group unless explicitly configured and explicitly addressed.
Two things worth thinking about before you enable a group:
Everyone in it can now influence your agent. Every message in that group enters the context of a model that holds your tool permissions. If exec is available, a group member — or someone who pastes a malicious block of text into the group — is talking to something with shell access. This is the prompt injection problem in its most concrete form, and it’s covered properly in The OpenClaw Threat Model.
People may not know it’s a bot. Depending on where you live and who’s in the group, quietly adding an AI that reads everything is at minimum a courtesy problem and potentially a legal one. Tell people.
The safe pattern: pair group access with a restricted agent. Read and search tools, no exec, no write. You keep the useful “what did we decide about the venue?” behaviour and remove the catastrophic failure mode.
A Note on iMessage and Signal
Both are supported, and both come with a caveat worth knowing before you invest an evening.
iMessage is macOS-only. The channel works by driving the Messages app on a Mac, which means your Gateway has to run on macOS — a Mac mini, or an always-on iMac. If you were planning a Linux server, iMessage is off the table. It’s the single most common reason people end up choosing Mac hardware for this.
{ channels: { imessage: { enabled: true, dmPolicy: "pairing", allowFrom: ["+15555550123", "user@example.com"], groups: { "*": { requireMention: true } } } }}Note that iMessage allowlists accept both phone numbers and Apple ID email addresses, because either can be the sending identity. If someone messages you from their email-linked Apple ID and you only allowlisted their phone number, they won’t get through.
Signal requires more setup than the others — it involves registering a number with the Signal infrastructure rather than dropping in a bot token. The config itself is simple:
{ channels: { signal: { enabled: true, dmPolicy: "pairing", allowFrom: ["+15551234567"], configWrites: true } }}Signal is the right choice if the content of your assistant conversations is genuinely sensitive and you want the transport to match. Bear in mind what it does and doesn’t buy you: the messages between you and the Gateway are end-to-end encrypted, but the agent still sends your prompts to a model provider unless you’re running a local model. Signal secures the leg you were probably least worried about.
Pairing in Practice
Both channels default to dmPolicy: "pairing", which is the right default and also the number one source of “my bot is ignoring me.”
Here’s what actually happens:
Unknown sender messages the bot │ ▼ Gateway: sender not in allowFrom │ ▼ Generate one-time code ──► sender sees "pairing required" │ (expires after 1 hour) ▼ Request queued ──► max 3 pending per account │ ▼ Operator approves: openclaw pairing approve telegram 428913 │ ▼ Sender added ──► subsequent messages handled normallyThe one-hour expiry and the three-request cap exist so a stranger who discovers your bot can’t bury you in approval prompts. If a code expires before you get to it, the sender just messages again.
The mistake to avoid: setting dmPolicy: "open" because pairing felt fiddly. open requires an explicit allowFrom: ["*"] precisely because the project wants you to think about it. An open DM policy on an agent with real tools means any stranger who finds your bot username is talking to something that can act on your machine.
If pairing is annoying you and you know exactly who should have access, the answer is allowlist, not open:
{ channels: { telegram: { dmPolicy: "allowlist", allowFrom: ["tg:123456789", "tg:987654321"] } }}No handshake, no codes, no strangers.
Isolate Sessions Before You Add People
The moment a second person can DM your bot, one setting stops being optional:
{ session: { dmScope: "per-channel-peer" }}Without it, DMs can share a single main session — meaning one person’s conversation may sit in the context window while your agent answers someone else. That’s a privacy failure, and it’s a quiet one: nothing errors, the agent just knows things it shouldn’t.
Set it before you approve the second pairing request, not after.
Things That Go Wrong
“The bot doesn’t reply at all.”
Work the order: is there a pending pairing request (openclaw pairing approve ...)? Is your ID in allowFrom in the right format? Is the channel actually connected — openclaw gateway status? The Control UI’s live session view answers all three faster than guessing.
“It works in DM but is silent in a group.”
requireMention is on. That’s by design. Address the bot directly, or set a per-group override.
“It replies to everything in the group.”
requireMention got switched off somewhere. Check channels.defaults, the per-channel block, and the per-group block — the most specific one wins.
“My Telegram allowlist doesn’t work.”
Almost always a @username where a numeric ID belongs. Get the number from @userinfobot.
“WhatsApp disconnects every few days.” Usually the phone has been offline too long, or the link was revoked from Linked Devices. Re-scan the QR. If it’s persistent, check whether battery optimisation on the phone is killing WhatsApp in the background.
“The QR code is unreadable in my terminal.” Use the Control UI. Some terminal fonts and colour schemes mangle block characters.
“My assistant replied to a group message with something private.”
Session scoping. Set dmScope: "per-channel-peer" and consider a separate, restricted agent for group contexts. This one is worth fixing the same day.
A Sane Starting Configuration
Both channels, locked down, ready to widen deliberately:
{ session: { dmScope: "per-channel-peer" },
channels: { defaults: { groupPolicy: "allowlist", implicitMentions: { replyToBot: true, quotedBot: true, threadParticipation: true } },
telegram: { botToken: "REPLACE_ME", dmPolicy: "pairing", allowFrom: ["tg:YOUR_NUMERIC_ID"], groups: { "*": { requireMention: true } } },
whatsapp: { dmPolicy: "pairing", allowFrom: ["+YOUR_NUMBER"], groupPolicy: "allowlist", groups: { "*": { requireMention: true } } } }}Note implicitMentions. Without it, every group message needs a literal @botname, which makes conversation stilted. With it, replying to the bot or continuing a thread counts as addressing it — which is how people actually talk.
Where to Go Next
You have a working, access-controlled channel. Two directions from here:
Slack, Discord and Teams — the workplace channels, where group dynamics, per-channel rules and the fact that colleagues are watching change the calculus.
Pairing and Allowlists — access control in depth, including what to do when you want to give someone limited access rather than all-or-nothing.