Day 5: Be Everywhere
You've been talking to your bot from one place, probably the Control UI or Telegram. Today you connect a second channel, decide who is allowed to talk to the bot on each one, and learn the pairing flow that keeps strangers out.
Time: ~45 minutes
Why Multi-Channel?
One Gateway, one agent, one workspace. Every channel you connect talks to the same agent, with the same SOUL.md, USER.md and MEMORY.md.
What is not shared automatically is the conversation itself. Each chat is its own session. By default all your direct messages share the agent's main session (session.dmScope: "main"), which is fine when you are the only person talking to the bot. As soon as anyone else can DM it, isolate DMs so one person's conversation is not visible to another (sessions):
{
session: {
dmScope: "per-channel-peer", // one session per channel + sender (recommended)
},
}
Group chats and server channels always get their own sessions.
The bot can also act across platforms: post a summary to a Slack channel while you talk to it on Telegram, for example. It does this with the message tool, and only on channels it is connected to and allowed to post in.
Add a Second Channel
Telegram ships with OpenClaw. Other official channels (Discord, Slack, WhatsApp, Signal and more) are separate plugins. The guided setup offers to install the plugin the first time you pick a channel:
openclaw channels add
Pick the channel, follow the prompts, and you're done. The rest of this section shows what each platform needs so you have it ready before you start.
Discord
- In the Discord Developer Portal, click New Application and give it a name. The bot user is created with the application.
- On the Bot page, click Reset Token and copy the token. (Despite the name, this generates your first token.)
- Under Privileged Gateway Intents, enable Message Content Intent. Enable Server Members Intent too if you want role-based allowlists.
- Under OAuth2 → URL Generator, select the
botscope plus Send Messages and Read Message History, open the generated URL and add the bot to your server. - In Discord, turn on Developer Mode (User Settings → Advanced) so you can right-click to copy your user ID and the server ID. OpenClaw matches Discord users by numeric ID.
Keep the token out of chat and out of openclaw.json in plain text. Upstream's setup reads it from an environment variable through a SecretRef:
{
channels: {
discord: {
enabled: true,
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
},
},
}
Put DISCORD_BOT_TOKEN=... in ~/.openclaw/.env so the Gateway service can read it after a restart. Full walkthrough: Discord setup.
To install the plugin yourself instead of through the guided setup:
openclaw plugins install @openclaw/discord
WhatsApp
WhatsApp links like WhatsApp Web: you scan a QR code with your phone. openclaw channels add offers to install the @openclaw/whatsapp plugin when you pick it, then:
openclaw channels login --channel whatsapp
On your phone, open WhatsApp → Linked devices → Link a device and scan the QR. The code expires quickly, so run this where you can see the terminal. Use a dedicated number if you can (WhatsApp).
Slack
Slack uses an app you create from a manifest, not a browser OAuth prompt:
- Install the plugin:
openclaw plugins install @openclaw/slack(or letopenclaw channels adddo it). - At api.slack.com/apps, choose Create New App → From a manifest, pick your workspace and paste the manifest from the Slack setup page.
- Install the app to the workspace and copy the bot token (
xoxb-…). Create an app-level token (xapp-…) withconnections:writefor Socket Mode.
{
channels: {
slack: {
mode: "socket",
botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
},
},
}
Socket Mode needs no public URL, which makes it the right choice for a home server.
Signal
Signal goes through signal-cli, which links to a Signal account like a desktop client:
openclaw plugins install @openclaw/signal
openclaw channels add
The wizard offers to install signal-cli if it is missing, then asks for the bot's number. You link the account with signal-cli link -n "OpenClaw" and scan the QR in Signal. A dedicated number is strongly recommended (Signal).
openclaw channels list --all shows every channel you can install. For details on each platform, see the Channels & Integrations guide and the upstream channel docs.
Apply the change
The Gateway watches openclaw.json and applies most changes by itself, restarting the affected channel when needed (hot reload). An invalid edit is skipped, so validate after every hand edit, and restart if a change does not seem to take effect:
openclaw config validate
openclaw gateway restart
A newly added env variable in ~/.openclaw/.env needs that restart.
Channel Status
# Channels you have configured
openclaw channels list
# Connection state, with a live credential check
openclaw channels status --probe
# Just one channel
openclaw channels status --channel discord --probe
# Recent log lines for a channel
openclaw channels logs --channel discord
If a channel drops:
- Token rejected: fix the token (or the env variable it points at), then
openclaw gateway restart. - WhatsApp logged out: run
openclaw channels login --channel whatsappagain and rescan. - Everything else:
openclaw status --deepruns a fuller connection check, andopenclaw doctorexplains common misconfigurations.
To disconnect a channel, openclaw channels remove --channel <id> disables it (add --delete to remove its config).
Who Can Talk to Your Bot
This is the most important part of today. Anyone who can message a tool-enabled agent can use its tools, so decide per channel who gets in.
Direct messages: dmPolicy
dmPolicy | What happens when an unknown person DMs the bot |
|---|---|
pairing (default) | They get a short pairing code; their message is not processed until you approve it. |
allowlist | Only senders listed in allowFrom get through. Everyone else is ignored. |
open | Anyone can talk to it. Requires allowFrom: ["*"]. Only for deliberately public bots with very limited tools. |
disabled | DMs are ignored. |
Source: shared channel policies.
For a personal bot, pairing is a good default. Once you and the few people you trust are approved, switching to allowlist closes the door completely.
Groups and servers: groupPolicy and mention gating
Group access is separate from DM access. Groups default to groupPolicy: "allowlist", so the bot only participates in groups or servers you list. In those groups it replies only when mentioned, by default (mention gating).
A worked example
This config keeps Telegram on pairing with mention-gated groups, limits Discord to one server and two channels, limits Slack to one channel, and allowlists a single WhatsApp number:
{
channels: {
telegram: {
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
discord: {
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
dmPolicy: "allowlist",
allowFrom: ["123456789012345678"], // your Discord user ID
groupPolicy: "allowlist",
guilds: {
"111111111111111111": { // your server ID
requireMention: true,
users: ["123456789012345678"], // who may use the bot in this server
channels: {
"bot-commands": { enabled: true, requireMention: false },
general: { enabled: true },
},
},
},
},
slack: {
mode: "socket",
botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
groupPolicy: "allowlist",
channels: {
C0123456789: { enabled: true, requireMention: true }, // Slack channel ID
},
},
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15555550123"],
groupPolicy: "allowlist",
groups: { "*": { requireMention: true } },
},
},
}
Notes:
- Discord and Slack match people and channels by ID. Discord's old
name#1234tags no longer exist. Useopenclaw channels resolveto turn names into IDs. - In Discord, a server's
channelsmap is itself an allowlist: channels not listed are ignored.roles: ["<role id>"]works alongsideusersif you enabled Server Members Intent. - To also wake the bot on a text pattern (for example
!bot), addgroupChat.mentionPatternsto the agent:agents.entries.main.groupChat.mentionPatterns: ["!bot"]. - There is no per-channel message rate limit setting. Control cost with model choice and by keeping the bot out of busy rooms.
More examples and the reasoning: Who can talk to the agent on the hardening page, and upstream's access control.
Pairing: Approving New People
Pairing is how a new person gets access to your bot's DMs when dmPolicy is pairing:
- Someone you don't know yet DMs the bot.
- The bot replies to them with an 8-character pairing code. Their message is not passed to the agent.
- They send you the code through some other channel (or you just look at the pending list).
- You, the operator, approve it.
# See pending requests for a channel
openclaw pairing list telegram
# Approve one (add --notify to tell them they're in)
openclaw pairing approve telegram ABCD2345 --notify
You can do the same in the Control UI under Settings → Channels → DM access requests, where Dismiss removes a request you don't want. There is no reject command: a request you ignore expires on its own after one hour, and each channel account keeps at most three pending requests (pairing).
Approval grants DM access only, not group access. The first approval from the CLI also makes that sender the command owner (commands.ownerAllowFrom) if you don't have one yet, which is where heartbeat alerts and exec approval prompts go.
A pairing request from someone you don't recognise just means a stranger found your bot and messaged it. Your credentials are not compromised. Don't approve it. If you get a lot of them, switch that channel to dmPolicy: "allowlist".
Pairing a device (the iOS or Android app, or another computer joining the Gateway as a node) is a different thing, managed with openclaw devices list and openclaw devices approve.
What You've Done Today
- Connected a second (and maybe third) chat platform, with tokens kept out of plain-text config
- Checked channel health with
openclaw channels status --probe - Isolated DM sessions with
session.dmScope - Decided who can reach the bot with
dmPolicy,allowFrom,groupPolicyand mention gating - Approved a new sender with the pairing flow
Tomorrow you build your own skill and give a second agent its own job.
Next: Day 6: Build Your Own — create custom skills and go multi-agent