OpenClaw Telegram Bot: How to Set Up an AI assistant in a Messenger
Most bot setup guides treat configuration as an afterthought — paste a token, press go, done. That works until it doesn't: the bot responds to strangers, the history balloons and costs spike, the service crashes overnight and nobody notices until morning. OpenClaw's Telegram integration has more moving parts than most guides acknowledge, and each one represents a deliberate choice about security, cost, and behavior.
This guide works through every meaningful configuration decision in sequence. By the end you'll have a deployment that actually behaves the way you intended — not just a deployment that works in a demo.
How a message travels through the system
OpenClaw is a gateway process that bridges two persistent connections: one to Telegram's API, one to your language model provider. A message from Telegram arrives, gets wrapped with your system prompt and whatever conversation context the gateway has accumulated, and travels to the model API. The response makes the return trip to the originating chat. The gateway owns the routing decision — a Telegram message always gets a Telegram reply, no exceptions, no redirects.
History is kept in a local store — a flat file or SQLite database depending on your setup. The gateway builds context from that store on each request. This is where a key cost dynamic lives: the longer a conversation runs without trimming, the more tokens travel in every subsequent request. That's not a bug, but it requires deliberate management.
Getting OpenClaw onto a machine
The installer detects the platform, pulls in Node.js if absent, and can optionally run an interactive setup wizard. Node 24 is the recommended runtime; anything from Node 22.14 upward is supported. On Windows, WSL2 is significantly more stable than the native environment. The pnpm package manager only enters the picture if you're compiling from source.
# macOS, Linux, or WSL2 — with wizard
curl -fsSL https://openclaw.ai/install.sh | bash
# macOS, Linux, or WSL2 — skip wizard
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard
# Windows PowerShell — with wizard
iwr -useb https://openclaw.ai/install.ps1 | iex
# Windows PowerShell — skip wizard
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
After installation, run a quick sanity check:
openclaw --version
openclaw doctor
openclaw gateway status
To make the gateway restart automatically after a reboot:
openclaw gateway install
This registers the right daemon type for the platform — LaunchAgent on macOS, a systemd user service on Linux and WSL2, a Scheduled Task on Windows.
Getting a bot token from Telegram
Telegram controls bot provisioning through a dedicated account called @BotFather. Open it in Telegram — the real one has a blue verification badge — and send /newbot. You'll pick a display name (shown in conversations) and a username (must end in "bot", cannot be changed later). At the end of that flow, BotFather issues a token.
That token is the bot's identity credential. It should be treated like a private key: never committed to a repository, never shared in a screenshot, never pasted into a public channel. Anyone who obtains it has full control over the bot — they can read every message it receives and send messages on its behalf.
Two BotFather settings are worth configuring before you leave:
- /setprivacy — by default, Telegram restricts bots in group chats to only see messages that directly address them by name. If the bot needs to see the full conversation in a group, this restriction has to be lifted. Note that toggling it on an already-deployed bot requires re-adding it to each affected group for Telegram to apply the change. Giving the bot admin rights in a group is an alternative that achieves full message visibility without touching this setting.
- /setjoingroups — determines whether other Telegram users can invite your bot into groups they control. For a private deployment, disabling this keeps the bot from showing up in unexpected places.
The config file, key by key
OpenClaw does not use a login flow for Telegram. Authentication happens through the config file at ~/.openclaw/openclaw.json, which the gateway reads on startup. Restart the gateway whenever the config changes.
A minimal working configuration:
{
"channels": {
"telegram": {
"enabled": true,
"botToken": "123:abc",
"dmPolicy": "pairing",
"groups": { "*": { "requireMention": true } }
}
}
}
If you'd rather not embed the token in the config file, set it as TELEGRAM_BOT_TOKEN in the environment instead. When both exist, the config file value takes precedence. The environment variable applies only to the default account.
The dmPolicy decision
dmPolicy is the single most consequential setting in the Telegram configuration. It governs who can reach the bot in direct messages and what happens when an unrecognized sender writes to it.
The four values:
- pairing — every new sender triggers a handshake. The bot withholds responses until an administrator approves the request through the CLI. Approved senders don't need to repeat the process. This is the default, and the right choice for any bot with tool access or connection to internal data.
- allowlist — only numeric Telegram user IDs explicitly listed under allowFrom can interact. Unknown senders receive nothing. The most restrictive option; ideal for personal bots.
- open — combined with allowFrom: ["*"], this makes the bot accessible to any Telegram user who finds it. Appropriate only for intentionally public deployments with no sensitive tool access.
- disabled — DMs are turned off entirely. Useful if the bot is meant exclusively for group contexts.
The operational risk of open with a wildcard is real: bot usernames are searchable, and a public bot connected to a capable model accumulates API charges quickly if discovered. If you're running a bot for yourself, allowlist with your own user ID is the tightest configuration available.
To find your numeric Telegram user ID without routing through third-party bots: start the gateway, send it a message, then run openclaw logs --follow and look for from.id in the output.
Starting the gateway and handling first contact
openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
With dmPolicy set to pairing, the first message from any new sender generates an approval request rather than a bot response. The sender gets a code. That code appears in the output of openclaw pairing list telegram. Once you run the approve command with it, the sender's session is established and messages start flowing normally. Codes become invalid after one hour if not acted on.
Group topology: what controls what
Groups have a more intricate permission structure than direct messages. Getting it wrong produces confusing silent failures — the bot simply ignores messages with no indication of why.
The gateway's group behavior is shaped by two separate configuration surfaces that don't interact with each other.
The group roster lives under channels.telegram.groups. This key, when present, functions as an explicit allowlist of which groups the bot will respond in at all. Omit it and the bot participates in any group it's added to. Set it with even one entry and all unlisted groups are silently excluded — which catches many people off guard when they add one group specifically and discover the bot stops responding in existing ones. The wildcard "*" can be combined with specific group IDs to keep general access while adding per-group configuration.
The sender filter operates independently, inside each permitted group. groupPolicy determines whether all group members can trigger responses (open), only those in an explicit list can (allowlist — the default), or nobody can (disabled). When set to allowlist, the groupAllowFrom field holds the permitted numeric user IDs. Without entries there, nobody in the group receives responses regardless of group roster status.
A group open to any member, with no mention requirement:
{
"channels": {
"telegram": {
"groups": {
"-1001234567890": {
"groupPolicy": "open",
"requireMention": false
}
}
}
}
}
A group locked to specific users who must address the bot by name:
{
"channels": {
"telegram": {
"groups": {
"-1001234567890": {
"requireMention": true,
"allowFrom": ["8734062810", "745123456"]
}
}
}
}
}
Group chat IDs are negative integers. To find one: run openclaw logs --follow and watch for the chat.id field when a message arrives, or query the Bot API's getUpdates endpoint directly. Group IDs belong in the groups section — not in groupAllowFrom, which holds only user IDs.
Choosing the right server size
Hardware requirements depend almost entirely on which kind of model you're running. For a polling setup that hands inference off to a cloud API, a modest VPS — 1 vCPU and 1 GB of RAM — handles the OpenClaw process comfortably. The gateway is lightweight; nearly all the computational work happens on the API provider's servers. Providers that offer hourly billing make it easy to validate a configuration cheaply before committing.
Webhook mode delivers messages somewhat faster (roughly 0.5–1.5 seconds versus 1–3 seconds for polling) but requires a publicly reachable HTTPS endpoint and a valid TLS certificate. The machine requirements are identical; the networking setup is more involved. For most conversational applications the latency difference isn't noticeable and the simplicity of polling is worth keeping.
Local models through Ollama are a different calculation. CPU-only inference on a 7-billion-parameter model typically produces responses in the 30–60 second range — workable for tests, awkward for actual conversation. Usable performance requires 16 GB of RAM as a baseline, and GPU access closes the gap considerably. The tradeoff is complete data isolation: nothing reaches an external API under any configuration.
Geography matters for latency even at these small server sizes. Telegram's infrastructure is concentrated in Frankfurt and Amsterdam; placing your VPS in either location meaningfully reduces the round-trip time on every message. While provisioning, apply standard hardening: close ports that aren't in use, replace password-based SSH with key authentication, and disable the password login option entirely.
What this actually gets used for
Specification-driven content review. A product team writes documentation drafts and routes them through a bot configured with the company's style guide as its system prompt. The bot flags passive voice, inconsistent terminology, and structural problems — inside the messenger the team already uses, without a separate review tool or workflow step.
Persistent project research context. A solo consultant uses a bot configured to maintain context across a long-running engagement. Rather than re-explaining the project to a fresh chat window each session, they continue from where the previous conversation ended. The local history store makes this possible without any external memory service.
Incident triage support for on-call engineers. A team adds a bot to their on-call group chat. When an alert fires, the engineer on duty can ask the bot to summarize similar past incidents, pull in relevant runbook steps, or help draft a status update — without switching between tools during a live incident.
Accessible contract review for a small firm. A legal team without dedicated technical resources runs a bot with a prompt tailored to their jurisdiction and practice area. Routine contract questions get a first-pass analysis in seconds. Edge cases escalate to a human.
Iterative prompt testing during model evaluation. A machine learning practitioner uses a private bot to experiment with system prompts and measure response quality across different models. The self-hosted setup means no rate limits interfere with rapid iteration, and the full conversation history stays available for comparison.
Operational failures worth anticipating
The token lands in a shared space. Version control is the classic vector, but it also happens through pastebins, Notion pages, and screenshots shared in public channels. A bot token that has been exposed should be treated as compromised — regenerate it through BotFather immediately. Old tokens remain functional until explicitly revoked; there is no expiration safety net.
The history store grows until costs spike. Each API request carries the accumulated conversation. In an active group chat with no trimming, a week of conversation can produce requests large enough to noticeably affect both latency and cost. Configure a MAX_HISTORY ceiling early — before the accumulation becomes a problem to fix rather than a parameter to set.
The gateway process terminates silently. A gateway that crashes at night stays down until someone notices the bot has stopped responding — which might be hours later if the bot handles anything asynchronous. A basic systemd status check running as a cron job and sending an email on failure is minimal but effective. Uptime Kuma or a similar lightweight monitor provides better visibility.
Group configuration changes produce unexpected silence. The most common group misconfiguration: adding an explicit entry to channels.telegram.groups for one specific group inadvertently creates an allowlist that excludes all other groups. If the bot was previously responding in several groups and goes quiet after a config change, this is almost always why. Adding "*": {} alongside the specific entry restores general access while keeping the per-group override.
The system prompt is too general to produce useful behavior. "Be helpful" is a non-instruction. A system prompt that specifies the domain, the user's likely expertise level, the preferred response format, and what the bot should decline to do produces a bot that behaves consistently and usefully. The prompt deserves as much attention as the infrastructure around it — usually more.
Tradeoffs to understand before committing
Self-hosting gives you things that managed services structurally can't: no message volume caps from the platform, no behavioral changes driven by another company's policy updates, full visibility into what data goes where. Because the framework is open source, extension is possible: webhook triggers, knowledge base integrations, custom tooling. The system can be made to do what you need rather than what the platform allows.
The costs are operational. The gateway needs someone to monitor it, update it, and rotate credentials when needed. For a solo deployment this amounts to occasional maintenance. For a team deployment it should be treated as infrastructure with its own ownership and runbook. Neither scenario is particularly demanding, but neither is zero.
Ballpark costs for a typical personal deployment: a minimal VPS runs $3–7 per month. Moderate usage — roughly 50–100 messages daily — against a capable cloud model adds $5–15 per month in API fees. Local models remove the API line item but require hardware capable of producing responses at conversational speed, which changes the cost structure substantially.
Frequently asked questions
Do I need programming experience to configure this?
The setup requires comfort with a terminal and editing a JSON config file. Writing code is not necessary. The bot's behavior, scope, and personality are all defined through a plain-text system prompt. Technical knowledge of what each config key does — which this guide covers — matters more than programming ability.
What happens to message content?
Telegram encrypts messages in transit between clients and its servers. OpenClaw then sends the message text to your configured model API over HTTPS. For cloud providers, that content is processed on their infrastructure under their data handling terms. Running a local model through Ollama is the only configuration that keeps message content entirely within your server. For regulatory or confidentiality requirements, local inference is the appropriate choice.
The bot is not responding. What should I check first?
Check whether the gateway process is still running: systemctl status openclaw. If it has exited, inspect the recent log output: journalctl -u openclaw -n 50. The most frequent causes are a bot token that was regenerated in BotFather without updating the config, exhausted API quota on the model provider side, and a server restart that didn't bring the daemon back up because openclaw gateway install was never run. Connectivity to api.telegram.org on port 443 is worth checking if other causes are ruled out.
Can I swap models without rebuilding anything?
Yes. Model configuration lives in openclaw.json and can be changed at any time. Restart the gateway after the change to apply it. The conversation history, system prompt, and access controls are all independent of which model is being used.
Local machine or remote server?
A local machine works well during development and personal testing when availability isn't a concern. For any deployment where responsiveness matters — especially one shared with other users — a persistent server is necessary. The gateway must be running when messages arrive; a machine that sleeps or reboots unpredictably will miss them. Entry-level server hosting is inexpensive enough that this is rarely a meaningful barrier.