TL;DR

Connecting OpenClaw to Telegram takes a token and a pairing approval. There's no login command. Create a bot with @BotFather, put the token in channels.telegram.botToken (or the TELEGRAM_BOT_TOKEN env variable), start openclaw gateway, DM your bot, then approve the code with openclaw pairing approve telegram <CODE>. If the bot went quiet right after an update, the usual cause is a corrupted plugin dependency tree, and the fix is openclaw doctor --fix followed by openclaw gateway restart.

The full setup, in order:

1. Message @BotFather in Telegram (that exact handle), send /newbot, save the token. 2. Put the token and a DM policy into config, or export TELEGRAM_BOT_TOKEN. 3. Start the gateway, DM the bot, then openclaw pairing list telegram and openclaw pairing approve telegram <CODE>. 4. For groups, wire two different IDs: your numeric user ID into groupAllowFrom, and the group chat ID (the negative -100… one) as a key under channels.telegram.groups.

Most of the pain comes from three things. Telegram has no channels login step, whatever a tutorial says. Updates can corrupt the channel plugin's dependency tree. And in recent versions group access doesn't inherit DM pairing, so a bot that answers your DMs can still sit silent in the group.

I run OpenClaw connected to Telegram on production servers, and when a bot goes silent, my phone is the monitoring system. Google this and you get the official docs plus a lot of posts rehashing them, some of them wrong. This page is the setup flow that matches the docs, then the failures I actually run into: breakage after updates, groups that go quiet, tokens that die, and polling that flaps because of host-level network problems.

There's no login command for Telegram

Get this out of the way first. OpenClaw's Telegram doc says it in bold: "Telegram does not use openclaw channels login telegram; configure token in config/env, then start gateway." A tutorial that opens with that login command was written without reading the doc, and I'd treat the rest of it accordingly.

So the whole shape is: token in config or environment, gateway up, then approve the pairing request that appears when you first DM the bot. There's no login step anywhere in it.

Connecting OpenClaw to Telegram

What you're setting up: a production-ready channel for bot DMs and groups, built on grammY. Long polling is the default mode and webhook is optional, so there's no inbound port to open and no public URL to maintain. The Telegram connection belongs to the gateway process, and routing is deterministic: a message that arrives on Telegram is answered on Telegram, and the model doesn't choose the channel.

Step 1: BotFather. In Telegram, message @BotFather (that exact handle), send /newbot, follow the prompts, save the token it hands you.

Step 2: token and DM policy in config.

{ channels: { telegram: {
  enabled: true, botToken: "123:abc", dmPolicy: "pairing",
  groups: { "*": { requireMention: true } },
} } }

The env fallback TELEGRAM_BOT_TOKEN=… works too, but only for the default account, and config takes precedence over env when both are set. If you point at a tokenFile instead, it has to be a regular file; symlinks are rejected.

Step 3: start and approve.

openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>

DM the bot first so there's a code to list. Pairing codes expire after an hour, then you DM again for a fresh one. The first pairing you approve sets commands.ownerAllowFrom (command ownership) if it isn't already set, so make sure that first approval is you.

Pairing in this article means the Telegram channel approving senders. If OpenClaw is refusing you with a gateway pairing error before Telegram even enters the picture (device pairing, a token mismatch between CLI and gateway), that's a different animal, covered in the gateway pairing guide.

Step 4: groups take two IDs. Your Telegram user ID (a positive number) goes into allowFrom or groupAllowFrom. The group's chat ID becomes a key under channels.telegram.groups. Supergroup chat IDs are negative and start with -100, and they go under groups, never into groupAllowFrom. Swapping those two is the most common group misconfiguration.

To find your user ID, DM the bot while running openclaw logs --follow and read from.id off the incoming message. Or ask the Bot API directly:

curl "https://api.telegram.org/bot<token>/getUpdates"

Pairing and DM policy: who's allowed in

dmPolicy has four settings. pairing is the default: every new DM sender waits for your approval. allowlist requires at least one numeric ID in allowFrom. open only works with allowFrom: ["*"], and disabled shuts DMs off entirely. For a bot only you will use, I'd go allowlist with your numeric user ID, so access is defined in config and doesn't depend on past pairing approvals.

If someone sends /start and gets silence, that's usually the DM policy blocking them. Run openclaw pairing list telegram and approve the code, or change the policy if you want different behavior.

And before anyone reaches for open: an open DM policy means whoever finds the bot talks to your agent. What that exposure costs, and how to keep allowlists tight, is covered in the security guide.

It stopped working after an update

This is the most common failure, and likely why you're here. The bot was answering before the update. Afterwards the Telegram channel is just gone. Recovery:

openclaw status --all
openclaw doctor --fix
openclaw gateway restart
openclaw status --all

In the first status --all, look for plugin load failed: dependency tree corrupted; run openclaw doctor --fix. What it means: the channel is still configured, but the plugin that runs it didn't survive the update; its dependency tree is in a bad state, so the load path fails. doctor --fix clears out stale plugin staging and auth shadows, and the restart brings the gateway up on clean state. The second status --all confirms the channel actually loaded.

People ask which version broke it. It isn't tied to one release: any update can leave a channel plugin unloadable this way, and the recovery is the same four commands.

Two more traps surface right after upgrades:

  • Your own allowlist locks you out. Run openclaw doctor --fix, or replace @username entries with numeric IDs.
  • DMs fine, groups suddenly dead. Recent versions draw a security boundary: group authorization no longer inherits DM pairing approvals. Pairing is for DMs only. If your group access was riding on an old pairing, that's what broke. Give groups their own groupAllowFrom or a per-group allowFrom.

More generally: after an update, check what actually loaded instead of trusting the success message. openclaw status --all and openclaw channels status --probe report what really came up. The full routine, including rollback, is in the update guide.

The bot is online but the group is silent

Three common causes, in the order I check them.

Privacy mode. Bots join groups with Telegram's Privacy Mode on by default, so the bot doesn't see every group message. Two ways out: BotFather /setprivacy, set it to Disable, then remove the bot from the group and add it back (the remove and re-add is what makes Telegram apply the change). Or make the bot a group admin. This is Telegram behavior; no OpenClaw setting overrides what Telegram won't deliver.

Mention required. requireMention defaults to true, so a healthy bot in a healthy group stays quiet until someone mentions it. The default is intentional; change requireMention if you want it to answer without a mention.

Wrong ID in the wrong list. groupPolicy defaults to allowlist (with open and disabled available). groupAllowFrom takes numeric user IDs, so a -100… group chat ID pasted there does nothing; it belongs under channels.telegram.groups. One more thing: if the config has no channels.telegram block at all, the runtime fails closed to groupPolicy="allowlist", which is the safe default.

`getMe returned 401`

Telegram rejected the token, so fix this before looking at anything else. Re-copy the token from BotFather, or recreate the bot, then update whichever source you use (botToken, tokenFile, or TELEGRAM_BOT_TOKEN) and restart the gateway.

Two details to check. Config takes precedence over env, so a stale botToken in config quietly wins over the fresh variable you just exported; check both places. And the bot's identity is cached in the state directory for up to 24 hours after a successful start, but changing or removing the token clears that cache, so a real token swap takes effect cleanly on restart.

Polling stalls, 409 conflicts, and the network underneath

Long polling is the default and needs nothing exposed: no inbound port, no public URL. Webhook mode exists (webhookUrl/webhookSecret, with a local listener on 127.0.0.1:8787), and most setups never need it.

The gateway keeps one active poller per token. A getUpdates 409 conflict means something else is polling with the same token: a second gateway, an instance that survived a migration, a script someone left running. Kill the duplicate. After I moved a bot between hosts, the "flaky bot" turned out to be two healthy pollers fighting over one token; the fix was stopping the old one, not debugging the new one.

The polling watchdog restarts the connection after 120 seconds without a completed getUpdates (that's the default). If it fires while the network is fine, tune pollingStallThresholdMs, sensible range 30000 to 600000, and only for false positives. If stalls persist after tuning, stop tuning. The problem is proxy, DNS, or IPv6 on the host.

On a server, polling stability is mostly a property of the host's egress to api.telegram.org. OpenClaw reconnects and retries, but if the route to api.telegram.org is broken, retrying won't help. On Node 22+, autoSelectFamily plus IPv6 can be the whole story. Force IPv4 with OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first or set channels.telegram.network.autoSelectFamily: false, and look at what DNS returns:

dig +short api.telegram.org A/AAAA

On a VPS with unstable egress, route through a proxy: channels.telegram.proxy: socks5://…. The standard HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY variables are honored too. Provisioning and hardening that VPS in the first place is its own guide.

Two errors that look like network problems but have config causes:

  • getMe or setMyCommands returns 404 while a direct curl with the same token works. That's apiRoot set to a full /bot<TOKEN> endpoint when it should be the Bot API root only. openclaw doctor --fix trims the /bot<TOKEN> tail.
  • setMyCommands rejected with BOT_COMMANDS_TOO_MUCH: too many plugin, skill, and custom commands registered with Telegram. Trim the list or disable the native command menu.

The diagnostic ladder

When you don't yet know which failure mode you're in, walk this top to bottom:

openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

Healthy reads as Runtime: running, Connectivity probe: ok, and a channel probe showing the transport connected. Each step narrows it: runtime up, gateway up, what the logs say while you DM the bot, what doctor flags, and whether the channel transport truly connects. For me, the first and last commands do most of the work.

Three general rules carry the rest. Config and token edits land on restart, not on save; a gateway will run on stale settings without any visible error. One token means one poller, so a 409 means finding and stopping the duplicate process. And after an update, check the probes instead of the updater's exit message.

When it's not OpenClaw's fault

Some of these problems sit outside OpenClaw entirely.

  • Privacy mode is a Telegram setting. A bot that can't see group messages until you flip /setprivacy and re-add it is documented Telegram behavior.
  • Egress problems are host problems. DNS handing out broken IPv6, a mandatory proxy, a VPS with a lossy route to api.telegram.org. The channel retries, but the root cause is at the host level. Fix the host, or point the proxy config at a route that works.
  • A duplicate poller is a process you started. If another process holds the same token, the 409s and the flapping aren't OpenClaw misbehaving. Find the duplicate and stop it.

If you'd rather not manage this yourself

Everything on this page is runnable by hand, and if you run your own box you've got what you need. It's also most of what Cain is, for people who'd rather not: OpenClaw on a dedicated server provisioned for you, one client per server, with Telegram wired up and managed for you. One button in the Assistant Control panel stands in for the token, config, and pairing steps above. Your prompts go straight to the model provider you already pay for, without a shared cloud in between. Both are fine answers; this article covers doing it yourself.

FAQ

How do I connect OpenClaw to Telegram? Create a bot with @BotFather (/newbot), put the token in channels.telegram.botToken or the TELEGRAM_BOT_TOKEN env variable, set a dmPolicy, start openclaw gateway, then approve your first DM with openclaw pairing approve telegram <CODE>. There is no openclaw channels login telegram step; the docs rule it out explicitly.

My OpenClaw Telegram bot stopped working after an update. What do I do? Run openclaw status --all, then openclaw doctor --fix, then openclaw gateway restart. The frequent cause is plugin load failed: dependency tree corrupted: the update left the channel plugin's dependency tree broken, doctor --fix cleans the staging, and the restart reloads it.

What's the Telegram pairing command in OpenClaw? openclaw pairing list telegram shows pending codes, and openclaw pairing approve telegram <CODE> approves one. Codes expire after one hour. There's no channels login for Telegram; pairing approval is the only step.

The bot is online but doesn't answer in my group. Why? Usually Telegram privacy mode: BotFather /setprivacy to Disable, then remove and re-add the bot so the change applies, or make it an admin. With requireMention on, it answers only when mentioned. Also confirm the group's -100… chat ID is a key under channels.telegram.groups.

What does `getMe returned 401` mean? Telegram rejected your bot token. Re-copy it from BotFather or recreate the bot, update botToken, tokenFile, or TELEGRAM_BOT_TOKEN, and restart the gateway. Config takes precedence over env, so check which source is actually in effect.

Why does polling keep dropping and reconnecting? Usually host egress: DNS, IPv6, or a proxy on the way to api.telegram.org. Check dig +short api.telegram.org A/AAAA, force ipv4first, or set channels.telegram.proxy. A getUpdates 409 means a second poller is using the same token. If the watchdog restarts a healthy connection, tune pollingStallThresholdMs.

Do I need a public server or a webhook to run OpenClaw in Telegram? No. Long polling is the default and needs no inbound port. Webhook mode is optional (webhookUrl/webhookSecret), and most setups never touch it.

Ilya Prudnikov runs private OpenClaw and Hermes instances. These are an operator's notes on keeping a Telegram channel alive, not project documentation; commands and defaults drift, so check OpenClaw's current docs for the authoritative version.