Problem: Telegram Bots on Polling Are Slow and Unreliable
You installed OpenClaw and it works on Telegram, but messages take 2-5 seconds to arrive because you're using long-polling instead of webhooks. Production setups need instant delivery and secure endpoints.
You'll learn:
- Set up Telegram webhooks with proper HTTPS
- Secure your bot with webhook secrets and pairing codes
- Configure reverse proxy for external access
- Troubleshoot common webhook failures
Time: 25 min | Level: Intermediate
Why This Happens
OpenClaw defaults to long-polling for simplicity—no public URL needed, works behind NAT. But polling checks for messages every few seconds, adding latency. Webhooks let Telegram push messages instantly to your server, but require HTTPS and a public endpoint.
Common symptoms:
- 2-5 second delays before bot responds
- Messages arrive out of order under load
- Higher resource usage from constant polling
- Can't scale beyond basic personal use
Prerequisites
Before starting, ensure you have:
- OpenClaw installed and running (
openclaw gateway statusshows active) - Node.js 22+ installed
- A domain name or public IP
- SSL/TLS certificate (Let's Encrypt works)
- Telegram bot token from @BotFather
Not setup yet? Run curl -fsSL https://openclaw.ai/install.sh | bash first.
Solution
Step 1: Create Your Telegram Bot
Open Telegram and message @BotFather:
/newbot
# Follow prompts:
# - Bot name: "My OpenClaw Assistant"
# - Username: "my_openclaw_bot" (must end with "bot")
Save the token: You'll see something like 7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
Expected: BotFather confirms creation and provides your bot token.
Step 2: Configure Webhook URL and Secret
OpenClaw needs your public HTTPS endpoint. Generate a secure webhook secret:
# Generate strong random secret
openssl rand -hex 32
Add to your OpenClaw config at ~/.openclaw/config.json:
{
"channels": {
"telegram": {
"botToken": "7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw",
"webhookUrl": "https://yourdomain.com/webhook/telegram",
"webhookSecret": "your-generated-secret-here",
"dmPolicy": "allowlist",
"allowFrom": []
}
}
}
Why this works: webhookSecret ensures only Telegram can send to your endpoint. Without it, anyone could spam fake messages to your bot.
If it fails:
- Error: "Invalid webhook URL": Must start with
https://(nothttp://) - Error: "Certificate verify failed": Self-signed certs don't work—use Let's Encrypt
Step 3: Set Up Reverse Proxy (Nginx)
Telegram needs HTTPS, but OpenClaw runs HTTP on port 18789. Use Nginx as a reverse proxy:
# /etc/nginx/sites-available/openclaw
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location /webhook/telegram {
# Verify webhook secret in header
if ($http_x_telegram_bot_api_secret_token != "your-generated-secret-here") {
return 403;
}
proxy_pass http://127.0.0.1:18789/webhook/telegram;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Rate limiting to prevent abuse
limit_req zone=webhook burst=20 nodelay;
}
}
# Rate limit zone definition (add to http block)
limit_req_zone $binary_remote_addr zone=webhook:10m rate=10r/s;
Enable and reload:
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Expected: nginx -t shows "test is successful"
Step 4: Register Webhook with Telegram
Tell Telegram to use webhooks instead of polling:
curl -X POST "https://api.telegram.org/bot7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw/setWebhook" \
-d "url=https://yourdomain.com/webhook/telegram" \
-d "secret_token=your-generated-secret-here"
Verify it worked:
curl "https://api.telegram.org/bot7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw/getWebhookInfo"
You should see:
{
"ok": true,
"result": {
"url": "https://yourdomain.com/webhook/telegram",
"has_custom_certificate": false,
"pending_update_count": 0
}
}
If it fails:
- pending_update_count > 100: Old polling updates stuck. Run
deleteWebhookfirst - last_error_message present: Check Nginx logs with
sudo tail -f /var/log/nginx/error.log
Step 5: Pair Your Telegram Account
OpenClaw requires explicit pairing for security. Message your bot /start in Telegram.
Expected: Bot sends back a 6-digit pairing code like ABC123
In your Terminal, approve the pairing:
openclaw pairing approve telegram ABC123
You should see: Approved telegram sender <your-user-id>
Test it: Send any message to your bot—response should arrive in under 500ms.
Verification
Check webhook is receiving messages:
# Watch OpenClaw logs in real-time
openclaw logs --follow
# Should see:
# [Telegram] Webhook received from 123456789
# [Agent] Processing message: "Hello"
Benchmark response time:
# Send message and time response
time curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
-d "chat_id=<YOUR_ID>" \
-d "text=ping"
You should see: Total time under 1 second (vs 2-5s with polling)
Security Hardening
Enable Group Message Filtering
By default, bots see all group messages if privacy mode is disabled. Lock it down:
{
"channels": {
"telegram": {
"groups": {
"-1001234567890": {} // Specific group ID only
},
"groupPolicy": "allowlist",
"groupAllowFrom": [123456789], // Your user ID
"requireMention": true // Must @mention bot in groups
}
}
}
Why: Prevents bot from processing every message in busy groups, reducing API costs.
Rotate Webhook Secret Monthly
# Generate new secret
NEW_SECRET=$(openssl rand -hex 32)
# Update config and Nginx
sed -i "s/webhookSecret.*/webhookSecret\": \"$NEW_SECRET\",/" ~/.openclaw/config.json
sed -i "s/X-Telegram-Bot-Api-Secret-Token.*/X-Telegram-Bot-Api-Secret-Token != \"$NEW_SECRET\"/" /etc/nginx/sites-available/openclaw
# Reload services
sudo systemctl reload nginx
openclaw gateway restart
# Update Telegram
curl -X POST "https://api.telegram.org/bot<TOKEN>/setWebhook" \
-d "url=https://yourdomain.com/webhook/telegram" \
-d "secret_token=$NEW_SECRET"
What You Learned
- Webhooks reduce message latency from seconds to milliseconds
- Webhook secrets prevent unauthorized POST requests
- Reverse proxies provide HTTPS without modifying OpenClaw
- Pairing codes ensure only authorized users can message your bot
Limitation: Webhooks require a public endpoint—if your IP changes frequently, use a dynamic DNS service or stick with polling.
Troubleshooting
Webhook Not Receiving Messages
# Check if Telegram can reach your endpoint
curl -v https://yourdomain.com/webhook/telegram
# Should return 405 Method Not Allowed (GET not supported)
# If timeout/connection refused, check firewall:
sudo ufw allow 443/tcp
Bot Responds Twice to Same Message
OpenClaw is running both polling and webhook. Disable polling in config:
{
"channels": {
"telegram": {
"polling": false, // Add this line
"webhookUrl": "https://yourdomain.com/webhook/telegram"
}
}
}
Certificate Errors in Logs
Telegram rejects self-signed certificates. Get a free Let's Encrypt cert:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com
Tested on OpenClaw 0.x (Feb 2026), Telegram Bot API 7.x, Ubuntu 24.04, Nginx 1.24