背景:OpenClaw 在 v2026.3.11 版本更新后,原本依赖的 openclaw-telegram-proxy 插件(通过 Cloudflare Worker 反代)失效。该插件通过修改 grammY 库的 API 请求地址,将 api.telegram.org 替换为自定义的 Cloudflare Worker 域名(如 telegram.chuchu-z.com),从而绕过大陆网络封锁。
插件失效原因:
- OpenClaw v2026.3.11 版本对 Telegram 频道的初始化流程进行了重构
- OpenClaw 的 Telegram 插件基于 grammY 库,启动时必须请求 Telegram API 初始化 bot
- 插件的 hook 机制失效,无法在 grammY 初始化前修改 API 地址
- 直接修改插件代码也无法适配新版本的内部结构
解决思路:
本地 nginx 拦截 + 反代
既然无法在应用层修改 API 地址,那就在系统层透明拦截 api.telegram.org 的请求,通过本地 nginx 反代转发到可访问的境外服务器。
通过四个组件的组合,让 Node.js “以为”在访问真实的 api.telegram.org,实际上流量走境外反代服务器:
Node.js (grammY)
↓ 请求 https://api.telegram.org
/etc/hosts 拦截
↓ 127.0.0.1 api.telegram.org
本地 nginx(自签名 SSL)
↓ proxy_pass
https://telegram.chuchu-z.com(境外反代)
↓
api.telegram.org(Telegram 真实服务器)
关键技术点:
/etc/hosts把api.telegram.org解析到本机127.0.0.1- 本地 nginx 监听 443,用自签名证书(CN=api.telegram.org)响应 HTTPS 请求
- Node.js 默认不信任自签名证书,需通过
NODE_EXTRA_CA_CERTS环境变量让其信任 - nginx 将请求透明转发到
telegram.chuchu-z.com(一个可访问 Telegram 的境外反代)
解决方案
前置准备:部署 Cloudflare Worker 反向代理
虽然 openclaw-telegram-proxy 插件失效,但 Cloudflare Worker 反代本身仍然可用,只是需要通过本地 nginx 来调用。
步骤 1:创建 Cloudflare Worker
- 登录 Cloudflare Dashboard
- 进入 Workers & Pages → Create application → Create Worker
- 选择 Hello World 模板,命名(如
telegram-proxy) - 编辑 Worker,粘贴以下代码:
const ALLOWED_METHODS = ['GET', 'POST', 'PUT', 'DELETE'];
const ALLOWED_HEADERS = [
'Content-Type', 'Authorization', 'User-Agent', 'Accept',
'Accept-Language', 'Accept-Encoding', 'Connection',
'Cache-Control', 'Pragma', 'X-Requested-With'
];
const REMOVE_HEADERS = [
'host', 'cf-connecting-ip', 'cf-ray', 'cf-visitor',
'x-forwarded-for', 'x-real-ip'
];
async function handleRequest(request) {
try {
if (request.method === 'OPTIONS') return handleCORS();
if (!ALLOWED_METHODS.includes(request.method)) {
return new Response('Method Not Allowed', { status: 405 });
}
const url = new URL(request.url);
const targetUrl = `https://api.telegram.org${url.pathname}${url.search}`;
const headers = new Headers();
for (const h of ALLOWED_HEADERS) {
const v = request.headers.get(h);
if (v) headers.set(h, v);
}
headers.set('Host', 'api.telegram.org');
headers.set('User-Agent', 'Cloudflare-Worker-Telegram-Proxy/1.0');
const opts = { method: request.method, headers, redirect: 'follow' };
if (request.method !== 'GET' && request.method !== 'HEAD') {
opts.body = request.body;
}
const response = await fetch(new Request(targetUrl, opts));
const respHeaders = new Headers();
for (const [k, v] of response.headers.entries()) {
if (!REMOVE_HEADERS.includes(k.toLowerCase())) respHeaders.set(k, v);
}
respHeaders.set('Access-Control-Allow-Origin', '*');
respHeaders.set('Cache-Control', 'no-cache, no-store, must-revalidate');
return new Response(response.body, {
status: response.status, statusText: response.statusText, headers: respHeaders
});
} catch (e) {
return new Response('Internal Server Error', { status: 500 });
}
}
function handleCORS() {
return new Response(null, {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': ALLOWED_METHODS.join(', '),
'Access-Control-Allow-Headers': ALLOWED_HEADERS.join(', '),
'Access-Control-Max-Age': '86400'
}
});
}
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === '/health' || url.pathname === '/status') {
event.respondWith(new Response(JSON.stringify({ status: 'ok' }), {
headers: { 'Content-Type': 'application/json' }
}));
return;
}
event.respondWith(handleRequest(event.request));
});
- 保存并部署
步骤 2:绑定自定义域名(关键)
workers.dev 域名在国内被墙,必须绑定自定义域名走 Cloudflare CDN。
前提:域名 NS 托管在 Cloudflare(如 chuchu-z.com,NS 为 *.ns.cloudflare.com)
- Workers & Pages → 选择你的 Worker → Settings → Domains & Routes
- Add → Custom Domain → 填入子域名(如
telegram.chuchu-z.com) - Cloudflare 自动创建 DNS 记录并签发 SSL 证书
- 等待状态变为 Active
步骤 3:验证 Worker 代理
curl https://telegram.chuchu-z.com/botINVALID/getMe
# 期望输出: {"ok":false,"error_code":404,"description":"Not Found"}
返回 Telegram API 的 JSON 响应即代理正常。
核心方案:本地 nginx 反代
步骤 1:生成自签名证书
openssl req -x509 -nodes -newkey rsa:2048 \
-keyout /etc/ssl/private/telegram-proxy.key \
-out /usr/local/share/ca-certificates/telegram-proxy.crt \
-days 3650 \
-subj "/CN=api.telegram.org" \
-addext "subjectAltName=DNS:api.telegram.org"
# 同时复制一份到 /etc/ssl/certs(供 NODE_EXTRA_CA_CERTS 使用)
cp /usr/local/share/ca-certificates/telegram-proxy.crt /etc/ssl/certs/telegram-proxy.crt
# 加入系统 CA(可选,供系统工具如 curl 使用)
/usr/sbin/update-ca-certificates
步骤 2:配置 nginx 反代
创建 /etc/nginx/sites-available/telegram-proxy:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name api.telegram.org;
ssl_certificate /etc/ssl/certs/telegram-proxy.crt;
ssl_certificate_key /etc/ssl/private/telegram-proxy.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
resolver 8.8.8.8 ipv6=off;
proxy_pass https://telegram.chuchu-z.com;
proxy_ssl_server_name on;
proxy_set_header Host telegram.chuchu-z.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
access_log /var/log/nginx/telegram-proxy.access.log;
error_log /var/log/nginx/telegram-proxy.error.log;
}
启用配置并重载 nginx:
ln -sf /etc/nginx/sites-available/telegram-proxy /etc/nginx/sites-enabled/telegram-proxy
/usr/sbin/nginx -t && /usr/sbin/nginx -s reload
步骤 3:修改 /etc/hosts
echo "127.0.0.1 api.telegram.org" >> /etc/hosts
步骤 4:让 Node.js 信任自签名证书
编辑 ~/.config/systemd/user/openclaw-gateway.service,在 [Service] 块末尾添加:
Environment=NODE_EXTRA_CA_CERTS=/etc/ssl/certs/telegram-proxy.crt
步骤 5:完整重启 OpenClaw
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
⚠️ 重要:
NODE_EXTRA_CA_CERTS是进程启动时读取的环境变量,使用openclaw gateway restart(SIGUSR1 热重启)不会重新加载环境变量,必须通过 systemd 完整重启服务。
步骤 6:验证
# 测试本地代理是否正常(应返回 Telegram API 的 JSON 响应)
curl -sk --resolve "api.telegram.org:443:127.0.0.1" \
"https://api.telegram.org/botINVALID/getMe"
# 期望输出(说明代理工作正常):
# {"ok":false,"error_code":404,"description":"Not Found"}
发送测试消息到 Telegram bot,确认推送功能恢复正常。
涉及的文件
| 文件 | 说明 |
|---|---|
/etc/ssl/certs/telegram-proxy.crt |
自签名证书(公钥) |
/etc/ssl/private/telegram-proxy.key |
私钥 |
/usr/local/share/ca-certificates/telegram-proxy.crt |
系统 CA 信任源 |
/etc/nginx/sites-available/telegram-proxy |
nginx 反代配置 |
/etc/nginx/sites-enabled/telegram-proxy |
软链接(启用) |
/etc/hosts |
添加 127.0.0.1 api.telegram.org |
~/.config/systemd/user/openclaw-gateway.service |
添加 NODE_EXTRA_CA_CERTS 环境变量 |
方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Cloudflare Worker + 插件 | 配置简单,无需修改系统 | 插件失效后不可用 | OpenClaw v2026.3.11 之前 |
| 本地 nginx 反代 | 不依赖插件,系统层透明拦截 | 需要修改 /etc/hosts 和 systemd 配置 | OpenClaw v2026.3.11 及之后 |
故障排查
- Worker 代理不通:
curl https://telegram.chuchu-z.com/health检查 Worker 状态 - 本地 nginx 不通:检查 nginx 日志
/var/log/nginx/telegram-proxy.error.log - 证书不信任:确认
NODE_EXTRA_CA_CERTS环境变量已生效(systemctl --user show-environment openclaw-gateway.service | grep NODE_EXTRA_CA_CERTS) - systemd 重启无效:确认使用
systemctl --user restart,而非openclaw gateway restart - 429 错误:Cloudflare Workers 免费版有请求限额(10万次/天),超限需升级