Activation: token-presence, not a flag
Channels auto-start as soon as the mesh resolves a usable token. There is no separateenabled: true flag — drop a token in and the channel comes up on next openlegion start. The mesh looks for each channel’s bot token in this order:
OPENLEGION_SYSTEM_<NAME>(mesh-tier env)OPENLEGION_CRED_<NAME>(agent-tier env)- Bare env (e.g.,
TELEGRAM_BOT_TOKEN) mesh.yamlchannels.<name>.bot_token
Pairing
On startup, each active channel prints a one-time pairing code to the console. Send/start <code> from your account in that channel to claim the channel — the first user to pair becomes the channel owner. After pairing, the channel persists the owner mapping (e.g., config/telegram_paired.json for Telegram).
Supported Channels
| Channel | Auth | Notes |
|---|---|---|
| CLI REPL | Built-in | Default channel. Full slash command set (see CLI Reference). |
| Telegram | OPENLEGION_CRED_TELEGRAM_BOT_TOKEN | Bot API. 4000-char chunks. Optional allowed_users list. |
| Discord | OPENLEGION_CRED_DISCORD_BOT_TOKEN | 1900-char chunks. Native slash commands + ! prefix fallback. /addkey is intentionally NOT a slash command — slash-command arguments are visible in the channel transcript, so !addkey (bang-prefix) is used instead. Requires Message Content Intent + bot and applications.commands OAuth scopes. |
| Slack | OPENLEGION_CRED_SLACK_BOT_TOKEN (xoxb-) and OPENLEGION_CRED_SLACK_APP_TOKEN (xapp-) | Socket Mode only (via slack-bolt). No public URL needed. 3000-char chunks. Per-user routing keyed on user_id:thread_ts. |
OPENLEGION_CRED_WHATSAPP_ACCESS_TOKEN + _PHONE_NUMBER_ID | Cloud API on Graph v21.0. Text only — non-text content (images, audio, documents) is dropped silently. See caveats below. | |
| Webhook | Dashboard-created hook | POST /webhook/hook/<hook_id>. Body cap 1MB; payload truncated to 3000 chars on dispatch. Optional HMAC-SHA256 via x-webhook-signature. Creation is dashboard-only — there is no /mesh/webhooks endpoint. |
Channel Configuration
API tokens are stored as environment variables:channels.<name> in config/mesh.yaml:
WhatsApp caveats
WhatsApp is the channel with the most operational gotchas:- Graph v21.0 Cloud API only.
- Text-only. Inbound non-text messages (images, audio, documents, stickers, locations) are dropped — the agent never sees them.
WHATSAPP_APP_SECRETis required in production. The webhook handler verifies inbound payloads with HMAC-SHA256. IfMESH_AUTH_TOKENis set andWHATSAPP_APP_SECRETis missing, the channel raisesRuntimeErrorat startup — it will not silently run unauthenticated.- The verify token regenerates on every restart unless you set
OPENLEGION_SYSTEM_WHATSAPP_VERIFY_TOKENexplicitly. Set it so your Meta-side webhook config stays stable.
Channel Commands
These commands work across all channels (CLI commands are documented in the CLI Reference):| Command | Description |
|---|---|
@agent <message> | Send message to a specific agent |
/use <agent> | Switch your active agent for this channel/user |
/status | Show fleet status |
/costs | Show today’s LLM spend |
/reset | Clear conversation with active agent |
/broadcast <msg> | Send message to all agents (project-scoped in dashboard) |
/steer <msg> | Inject a message into a busy agent’s context (rate-limited) |
/addkey <svc> [key] | Add an API credential to the vault (Discord: bang-prefix !addkey) |
/help | Show available commands |
/quit, /exit | (CLI only) leave the REPL |
/add, /agent, /remove, /restart, /history, /blackboard, /queue, /cron, /project, /credential, /removekey, /logs, /traces (alias /debug).
Per-channel routing semantics
Routing semantics differ slightly per channel:- Telegram / Discord: per-user. Each user’s messages route to the agent they’ve
/use-d. - Slack: composite
user_id:thread_ts. The same user gets a separate active-agent per thread. - WhatsApp: per-user, keyed on phone number.
- CLI: single-user (the REPL session itself).
