2026-01-06 18:25:52 +00:00
---
2026-01-13 06:16:43 +00:00
summary: "Routing rules per channel (WhatsApp, Telegram, Discord, Slack) and shared context"
2026-01-06 18:25:52 +00:00
read_when:
2026-01-13 06:16:43 +00:00
- Changing channel routing or inbox behavior
2026-01-31 16:04:03 -05:00
title: "Channel Routing"
2026-01-06 18:25:52 +00:00
---
2026-01-31 21:13:13 +09:00
# Channels & routing
2026-01-06 18:25:52 +00:00
2026-01-30 03:15:10 +01:00
OpenClaw routes replies **back to the channel where a message came from** . The
2026-01-13 06:16:43 +00:00
model does not choose a channel; routing is deterministic and controlled by the
2026-01-08 23:06:56 +01:00
host configuration.
## Key terms
2026-01-13 06:16:43 +00:00
- **Channel**: `whatsapp` , `telegram` , `discord` , `slack` , `signal` , `imessage` , `webchat` .
- **AccountId**: per‑ channel account instance (when supported).
2026-01-08 23:06:56 +01:00
- **AgentId**: an isolated workspace + session store (“brain”).
2026-01-08 23:25:45 +01:00
- **SessionKey**: the bucket key used to store context and control concurrency.
2026-01-08 23:06:56 +01:00
## Session key shapes (examples)
Direct messages collapse to the agent’ s **main** session:
- `agent:<agentId>:<mainKey>` (default: `agent:main:main` )
2026-01-13 06:16:43 +00:00
Groups and channels remain isolated per channel:
2026-01-08 23:06:56 +01:00
2026-01-13 06:16:43 +00:00
- Groups: `agent:<agentId>:<channel>:group:<id>`
- Channels/rooms: `agent:<agentId>:<channel>:channel:<id>`
2026-01-08 23:06:56 +01:00
Threads:
- Slack/Discord threads append `:thread:<threadId>` to the base key.
- Telegram forum topics embed `:topic:<topicId>` in the group key.
Examples:
- `agent:main:telegram:group:-1001234567890:topic:42`
- `agent:main:discord:channel:123456:thread:987654`
## Routing rules (how an agent is chosen)
Routing picks **one agent** for each inbound message:
2026-01-09 12:44:23 +00:00
1. **Exact peer match** (`bindings` with `peer.kind` + `peer.id` ).
2026-02-14 10:05:09 +08:00
2. **Parent peer match** (thread inheritance).
3. **Guild + roles match** (Discord) via `guildId` + `roles` .
4. **Guild match** (Discord) via `guildId` .
5. **Team match** (Slack) via `teamId` .
6. **Account match** (`accountId` on the channel).
7. **Channel match** (any account on that channel, `accountId: "*"` ).
8. **Default agent** (`agents.list[].default` , else first list entry, fallback to `main` ).
When a binding includes multiple match fields (`peer` , `guildId` , `teamId` , `roles` ), **all provided fields must match** for that binding to apply.
2026-01-08 23:06:56 +01:00
The matched agent determines which workspace and session store are used.
2026-01-09 21:29:07 +01:00
## Broadcast groups (run multiple agents)
2026-01-30 03:15:10 +01:00
Broadcast groups let you run **multiple agents** for the same peer **when OpenClaw would normally reply** (for example: in WhatsApp groups, after mention/activation gating).
2026-01-09 21:29:07 +01:00
Config:
```json5
{
broadcast: {
strategy: "parallel",
"120363403215116621@g .us": ["alfred", "baerbel"],
2026-01-31 21:13:13 +09:00
"+15555550123": ["support", "logger"],
},
2026-01-09 21:29:07 +01:00
}
```
2026-02-07 15:40:35 -05:00
See: [Broadcast Groups ](/channels/broadcast-groups ).
2026-01-09 21:29:07 +01:00
2026-01-08 23:06:56 +01:00
## Config overview
2026-01-09 12:44:23 +00:00
- `agents.list` : named agent definitions (workspace, model, etc.).
2026-01-13 06:16:43 +00:00
- `bindings` : map inbound channels/accounts/peers to agents.
2026-01-08 23:06:56 +01:00
Example:
```json5
{
2026-01-09 12:44:23 +00:00
agents: {
2026-01-31 21:13:13 +09:00
list: [{ id: "support", name: "Support", workspace: "~/.openclaw/workspace-support" }],
2026-01-09 12:44:23 +00:00
},
bindings: [
2026-01-13 06:16:43 +00:00
{ match: { channel: "slack", teamId: "T123" }, agentId: "support" },
2026-01-31 21:13:13 +09:00
{ match: { channel: "telegram", peer: { kind: "group", id: "-100123" } }, agentId: "support" },
],
2026-01-08 23:06:56 +01:00
}
```
## Session storage
2026-01-30 03:15:10 +01:00
Session stores live under the state directory (default `~/.openclaw` ):
2026-01-08 23:06:56 +01:00
2026-01-30 03:15:10 +01:00
- `~/.openclaw/agents/<agentId>/sessions/sessions.json`
2026-01-08 23:06:56 +01:00
- JSONL transcripts live alongside the store
You can override the store path via `session.store` and `{agentId}` templating.
## WebChat behavior
WebChat attaches to the **selected agent** and defaults to the agent’ s main
2026-01-13 06:16:43 +00:00
session. Because of this, WebChat lets you see cross‑ channel context for that
2026-01-08 23:06:56 +01:00
agent in one place.
## Reply context
Inbound replies include:
2026-01-31 21:13:13 +09:00
2026-01-08 23:06:56 +01:00
- `ReplyToId` , `ReplyToBody` , and `ReplyToSender` when available.
- Quoted context is appended to `Body` as a `[Replying to ...]` block.
2026-01-13 06:16:43 +00:00
This is consistent across channels.