Telegram is the fastest way to turn a phone into an agent dispatcher. You type a command, your OpenClaw instance executes a task, and a reply lands in your pocket thirty seconds later. This guide walks through the full setup: creating the bot with BotFather, choosing webhook or long-polling, mapping chat commands to agent tasks, and locking the whole thing down with chat ID allowlists and approval buttons. It is written for solo founders and small teams who want to ship work from a phone.
Why Drive OpenClaw From Telegram
The dashboard is the obvious UI for OpenClaw. It is also the wrong UI when you are walking to the subway, sitting in a client meeting, or standing in line for coffee. Telegram fills that gap. You open a chat, type /deploy staging, and your OpenClaw agent runs the task on your behalf. No laptop, no VPN, no tab switching.
Three use cases cover most of the value:
- Dispatch on the go. Kick off a research agent, a lead-enrichment run, or a deploy from your phone.
- Approvals in the pocket. The agent proposes an action, you tap “Approve” or “Reject” from an inline button.
- Status pings. The agent finishes a long-running task and Telegram buzzes with the result.
This is not a replacement for the dashboard. It is the remote control.
Prerequisites
Before you start:
- A running OpenClaw instance, version 2026.2 or later, with CLI access.
- A Telegram account (the bot will run under your control, but it is a separate identity).
- Shell access to the machine running OpenClaw.
- A domain with HTTPS if you plan to use webhook mode. Long-polling does not require this.
If you have never created a Telegram bot before, our how to create a telegram bot token primer covers the BotFather flow in detail. This guide gives you the condensed version and then jumps into OpenClaw.
Step 1: Create a Bot With BotFather
Open Telegram and search for @BotFather. Start a chat, then run:
/newbot
BotFather will ask for two things:
- A display name for the bot (e.g. “Acme Ops Bot”). This is shown to users.
- A username ending in
bot(e.g.acme_ops_bot). This has to be globally unique on Telegram.
Once the bot is created, BotFather sends you a token that looks like:
123456789:ABCDEFghijklmnopqrstuvwxyz-your-token-here
Treat this like a password. Anyone holding it can impersonate your bot. Store it in your .env file and never paste it into a public repo or group chat.
While you are still talking to BotFather, run:
/setprivacy
Select your new bot, then choose Disable. This lets the bot see every message in a group, not just messages that mention it. For a personal ops bot, this is usually what you want. For shared group channels where privacy matters, leave it on and design around mentions.
Step 2: Pick Webhook or Long-Polling
OpenClaw supports both transport modes. The choice matters more than most tutorials suggest.
| Factor | Long-Polling | Webhook |
|---|---|---|
| Setup effort | Minimal | Requires HTTPS endpoint |
| Latency | 1-3 seconds | 200-800 milliseconds |
| Works behind NAT | Yes | No (needs public URL) |
| SSL certificate | Not needed | Required |
| Best for | Laptops, home servers, dev | Production, cloud deployments |
| Debugging | Easier (just logs) | Harder (request inspection) |
If you are a solo founder running OpenClaw on a home server or a laptop, use long-polling. The latency penalty is real but tolerable, and you skip the entire HTTPS setup. Once you move to a cloud instance with a real domain, switch to webhooks.
Step 3: Configure the OpenClaw Telegram Channel
OpenClaw stores channel credentials in its config database, not in plain text files. Set the token with the CLI:
openclaw channels config telegram \
--bot-token "$TELEGRAM_BOT_TOKEN" \
--mode polling
For webhook mode instead:
openclaw channels config telegram \
--bot-token "$TELEGRAM_BOT_TOKEN" \
--mode webhook \
--webhook-url "https://ops.example.com/openclaw/telegram"
Enable the channel and verify the connection:
openclaw channels enable telegram
openclaw channels status --probe
A healthy probe looks like:
telegram connected bot=@acme_ops_bot mode=polling latency=412ms
If you see disconnected or unauthorized, the token is wrong or has whitespace. If you see 409 Conflict, a second process is already polling with the same token (see the two-bot pattern below). For everything else, jump to the openclaw telegram bot troubleshooting guide.
Step 4: Find Your Chat ID and User ID
Telegram identifies chats and users by numeric IDs, not by @username. You need the numeric IDs for the allowlist step that follows.
Start a chat with your bot. Send any message (e.g. hello). Then on your OpenClaw server, run:
openclaw channels telegram inspect --last 5
You will see entries like:
chat_id=847392017 user_id=847392017 type=private text=hello
chat_id=-1001234567890 user_id=847392017 type=supergroup text=@acme_ops_bot /status
Copy the numbers. A private chat has a positive chat_id equal to your own user ID. A group or supergroup has a large negative number. You will paste these into the allowlist in the next step.
If the inspect command returns nothing, the bot has not received any messages yet, or privacy mode is still on in a group context.
Step 5: Map Telegram Messages to Agent Tasks
OpenClaw’s trigger system converts an incoming Telegram update into an agent task. The mapping lives in the channel’s routing config.
Create a routing file at ~/.openclaw/routes/telegram.yaml:
routes:
- match:
command: "/status"
agent: "ops-status"
args: {}
- match:
command: "/deploy"
agent: "deploy-runner"
args:
environment: "${arg1}"
requires_approval: true
- match:
command: "/research"
agent: "research-writer"
args:
topic: "${args_joined}"
- match:
text_regex: "^summarize (.+)"
agent: "summarizer"
args:
url: "${match1}"
Load the routes:
openclaw channels telegram routes load ~/.openclaw/routes/telegram.yaml
Four route patterns cover most needs:
| Telegram input | Handler | Result |
|---|---|---|
/status | ops-status agent | Bot replies with system status |
/deploy staging | deploy-runner agent with approval gate | Bot asks for confirmation, then deploys |
/research OpenClaw vs LangGraph | research-writer agent | Agent runs, bot replies with findings |
summarize https://... | summarizer agent | Agent fetches and summarizes the URL |
The requires_approval: true flag is the bridge into the approval flow described in Step 7.
Step 6: Lock the Bot Down
A Telegram bot with open access is a liability. Anyone who finds the bot’s username can send it commands. Without limits, that person can run your agents. Apply three layers.
Layer 1: Chat ID allowlist
Only respond to messages from chat IDs you have explicitly approved.
openclaw channels telegram allowlist add 847392017
openclaw channels telegram allowlist add -1001234567890
openclaw channels telegram allowlist enforce --strict
With --strict set, any message from a non-allowlisted chat is dropped before it reaches the router. The bot never replies, so strangers cannot even confirm the bot exists.
Layer 2: User ID allowlist for sensitive commands
Within an allowlisted group chat, you may want to restrict destructive commands to specific users. Edit the route:
- match:
command: "/deploy"
agent: "deploy-runner"
args:
environment: "${arg1}"
requires_approval: true
allowed_user_ids:
- 847392017
- 523918471
Anyone else running /deploy in the group gets a polite refusal.
Layer 3: Command whitelist
Disable catch-all text matching in production. If a route does not match, drop the message. This is the default when you set:
openclaw channels telegram policy set --unknown-command drop
Alternative policies are echo (useful for debugging) and help (replies with a list of available commands).
Step 7: Build the Approval Flow for Destructive Actions
Any command that writes, deploys, sends email, or moves money should not execute on the first message. Use Telegram’s inline keyboard for a confirm loop.
When a route has requires_approval: true, OpenClaw sends an approval card instead of executing. The outbound payload looks like:
{
"chat_id": 847392017,
"text": "Deploy staging?\n\nBranch: main\nCommit: a1b2c3d\nAgent: deploy-runner",
"reply_markup": {
"inline_keyboard": [[
{ "text": "Approve", "callback_data": "approve:task_7f3a2" },
{ "text": "Reject", "callback_data": "reject:task_7f3a2" }
]]
}
}
When you tap Approve, Telegram sends a callback_query back to OpenClaw. The channel handler matches the task_7f3a2 ID, verifies the user ID is still allowed, and executes the queued task. The bot then edits the original message to show the outcome, so the chat stays tidy.
Three details make this pattern safe in practice:
- Task IDs expire. An approval token older than 10 minutes is refused. This prevents replay attacks and stale approvals on stale context.
- The approving user is logged.
callback_query.from.idis recorded as the approver, even in group chats. - The original message is edited, not replied to. This keeps the chat readable and makes the audit trail obvious.
This is the single biggest UX upgrade over bots that just reply with text. Approvals on your phone become a one-tap ritual.
Rate Limits and Cost Caveats
Telegram’s Bot API is free, but it has hard rate limits you need to design around.
| Limit | Value | Mitigation in OpenClaw |
|---|---|---|
| Global outbound | 30 messages per second | Built-in queue drains at 25/sec |
| Per-chat (private) | 1 message per second | Coalesce status updates into one message |
| Per-group | 20 messages per minute | Use message edits, not new messages, for progress |
| Media uploads | 50 MB per file | Chunk or link instead |
The real cost is not Telegram. It is the LLM calls your agents make. A reasoning agent that costs $0.05 per run is cheap until a curious user sends 400 commands in an afternoon. Set per-user daily quotas in the channel config:
openclaw channels telegram quotas set --user-daily 50 --group-daily 200
At 20 commands per day to a mid-tier reasoning agent, realistic monthly LLM spend is in the $25 to $45 range. At 200 commands per day, the same setup is $250 to $450. Quotas are cheap insurance.
A Two-Bot Pattern for Dev and Prod
Telegram only allows one consumer per bot token in polling mode. If you try to run the same bot from your laptop while production is also polling, both get intermittent 409 Conflict errors and messages get lost.
Create two bots with BotFather: acme_ops_bot and acme_ops_dev_bot. Use separate tokens in separate environments:
# Production (cloud)
openclaw channels config telegram --bot-token "$TELEGRAM_PROD_TOKEN" --mode webhook
# Development (laptop)
openclaw channels config telegram --bot-token "$TELEGRAM_DEV_TOKEN" --mode polling
Iterate on the dev bot. Test new routes, try new approval flows, break things. Promote to prod only after the dev bot behaves the way you want. This pattern also doubles as a safety net: if the prod bot misbehaves, you can disable it without losing your development setup.
Observability: Log Every Command
An agent triggered from chat is still an agent executing code. Log what happened.
OpenClaw emits a structured event for every Telegram-triggered task. Tail them:
openclaw logs --follow --json --filter channel=telegram
Sample entry:
{
"timestamp": "2026-04-14T09:12:34Z",
"channel": "telegram",
"chat_id": 847392017,
"user_id": 847392017,
"command": "/deploy staging",
"task_id": "task_7f3a2",
"agent": "deploy-runner",
"approved_by": 847392017,
"duration_ms": 42318,
"result": "success"
}
Ship these to your observability tool of choice. At minimum, grep the log file weekly and confirm nothing unexpected ran. If a command appears that you did not send, rotate the bot token immediately and audit the allowlist.
Frequently Asked Questions
How do I create a Telegram bot for OpenClaw?
Open Telegram, start a chat with @BotFather, run /newbot, give it a display name and a username ending in bot, then copy the token BotFather sends back. Store the token in .env and register it with openclaw channels config telegram --bot-token "$TELEGRAM_BOT_TOKEN" --mode polling.
Should I use webhook or long-polling? Long-polling if you are running OpenClaw on a laptop or home server with no public HTTPS endpoint. Webhooks if you have a production deployment with a real domain. Webhooks are faster (200-800ms vs 1-3s) but require SSL setup.
How do I restrict the bot to specific chat IDs?
Run openclaw channels telegram allowlist add <chat_id> for each allowed chat, then openclaw channels telegram allowlist enforce --strict. Messages from any other chat are dropped silently.
Can I run the same Telegram bot on two OpenClaw instances?
Not in polling mode. Telegram allows one consumer per token, and a second poller causes 409 Conflict errors. Create a second bot with BotFather for your dev or staging environment.
How do I map a Telegram command to an agent task?
Write a YAML routing file at ~/.openclaw/routes/telegram.yaml with match and agent entries, then load it with openclaw channels telegram routes load. Commands, text regex, and callback data can all trigger routes.
Does Telegram charge for bot API usage? No. The Telegram Bot API is free. Your cost is the LLM inference your agents perform, which is not related to Telegram pricing. Set per-user quotas to cap runaway usage.
How do I approve or reject an action from chat?
Mark the route with requires_approval: true. OpenClaw will send an inline keyboard with Approve and Reject buttons. Tapping Approve fires a callback_query back to OpenClaw, which verifies your user ID and runs the task.
Why is my bot silent in group chats?
Privacy mode is probably on. Open BotFather, run /setprivacy, select your bot, and choose Disable. Then remove the bot from the group and re-add it so Telegram picks up the new setting.
Key Takeaways
- Telegram turns OpenClaw into a pocket remote. Dispatch tasks, approve actions, and read results without opening a laptop.
- Start with long-polling. Move to webhooks when you have a production deployment with HTTPS.
- Allowlist chat IDs and user IDs before you invite anyone else. Open bots are liabilities.
- Use the inline-keyboard approval flow for any destructive command. One tap is the right friction level.
- Run two bots (dev and prod) to avoid polling conflicts and to iterate safely.
- Set per-user quotas. Telegram is free; your LLM is not.
- Log every command with its chat ID, user ID, and outcome. Audit weekly.
If your bot stops responding after following this guide, our openclaw telegram bot troubleshooting guide covers the common failure modes: bad tokens, privacy mode, webhook conflicts, and post-upgrade regressions.
SFAI Labs