通过代理使用 Telegram Bot API:配置长轮询、Webhook 与 429 错误处理
引言:这份指南能帮你解决什么
如果你至少启动过一次 Telegram 机器人,就会知道一件令人头疼的事。机器人本身一个晚上就能写出来,但让它稳定运行却变成了一个独立项目。消息延迟收到、更新丢失、服务器突然返回 429 错误,Webhook 毫无征兆地停止被调用。再加上所有请求都必须经过的代理,故障点直接翻倍。
这份分步指南专门解决这些问题。你将学会如何通过代理服务器使用 Telegram Bot API,让机器人不崩溃、不丢消息、正确应对频率限制。我们不会去研究 MTProto 协议,也不会搭建代理监控系统。我们的主题更聚焦、更实用:通过代理向 api.telegram.org 发送 HTTP 请求、两种获取更新的方式,以及正确应对限制。
最终你能得到什么
- 一个能通过你的代理(HTTP 或 SOCKS5)向 Telegram Bot API 发送请求的可运行机器人。
- 配置好的长轮询,不会因超时断开,也不会重复消息。
- 一个带 HTTPS 和密钥令牌的 Webhook,在你的服务器上接收更新。
- 一个现成的请求封装,遇到 429 错误时自动等待,然后重试发送。
- 理解你的项目该选哪种模式:轮询还是 Webhook。
这份指南适合谁
适合做群发、线索通知和广告数据统计机器人的营销人员和投放人员。适合需要固定、可预测出口 IP 做服务器请求的开发者。适合那些机器人服务客户、绝不能一小时不回话的企业主。如果你在用移动代理并希望把机器人流量走代理,你来对地方了。
需要提前知道什么
我们会从零讲解每一步,但几个基础技能会让过程轻松很多。会用终端或命令行、能复制命令、能运行 Python 脚本会很有帮助。了解什么是 HTTP 请求和 JSON 更好,但我们会用大白话提醒你。进阶内容单独放在一个章节里,新手可以跳过,不影响最终结果。
需要多少时间
准备和创建机器人约 20 分钟。配置代理和第一次成功请求再花 20-30 分钟。长轮询半小时就能跑起来。Webhook 需要 40-60 分钟,因为要申请 HTTPS 证书。处理 429 错误再加 20 分钟。总共两到三小时,不慌不忙,每步都验证。
前期准备:工具和权限
在写第一行代码之前,先把需要的东西都准备好。这样你就不会做到一半停下来找代理密码或研究怎么装库。
需要的工具和权限
- Telegram 账号,已绑定手机号。用它通过官方机器人 BotFather 创建你的机器人。
- 代理访问信息:服务器地址、端口、用户名和密码。在 mobileproxy.space 个人后台里,这些信息显示在已购代理的卡片上。通常会提供两个端口:一个用于 HTTP 连接,另一个用于 SOCKS5。两个都记下来。
- 电脑或服务器,已安装 Python 3.10 或更高版本。Webhook 需要一台有公网 IP 和域名的服务器,在家用电脑上 Webhook 无法工作。
- curl 工具。Windows 10 和 11、macOS、Linux 都已内置。用命令
curl --version检查。 - 文本编辑器:VS Code、Notepad++ 或任何你写代码顺手的工具。
系统要求
轮询几乎没什么要求:只要能联网的机器都行,笔记本也可以。机器人只占几十兆内存。Webhook 需要一台最低配置的 VPS:1 核 CPU、1 GB 内存、Ubuntu 22.04 或 24.04。必须有一个指向该服务器 IP 的域名,并在防火墙中开放 443 端口。
需要安装什么
- 打开终端。
- 用
python3 --version检查 Python。在 Windows 上命令可能是python --version。 - 创建项目文件夹:
mkdir tgbot-proxy,然后进入该目录cd tgbot-proxy。 - 创建虚拟环境:
python3 -m venv venv。激活它:Linux 和 macOS 上用source venv/bin/activate,Windows 上用venv\Scripts\activate。 - 安装库:
pip install requests[socks] flask。requests 包负责向 Telegram Bot API 发请求,socks 扩展用于 SOCKS5 代理,Flask 用来接收 Webhook。
备份与数据安全
把机器人 Token 当作银行 App 密码来对待。拿到它的人就能以你的机器人名义给客户发消息。创建一个 .env 文件存放 Token 和代理信息,永远不要把它推送到公开仓库。如果机器人已在运行、你正把它迁到代理上,先保存现有配置,有数据库的话做一次导出,并记录 getWebhookInfo 方法的结果。这样回滚只需两分钟。
建议:专门建一个测试机器人来做实验。本指南的所有步骤先在它上面跑一遍,验证无误的配置再迁移到正式机器人上。这样就不会影响与真实客户的沟通。
基础概念:Telegram Bot API 是怎么运作的
用大白话讲清几个关键术语。不了解它们,后面的步骤看起来像魔法;了解之后,一切就变得合乎逻辑、可以预测。
Telegram Bot API
它就是一个普通的 HTTP 接口。你的代码向 https://api.telegram.org/bot<TOKEN>/<method> 这样的地址发请求,Telegram 服务器返回 JSON 对象。比如 getMe 方法返回机器人信息,sendMessage 向聊天发送文本。不需要特殊库,curl 或 requests 就够了。正因为如此,Telegram Bot API 走代理非常容易:它和任何网站走 HTTPS 的流量一样。
更新(updates)
机器人的每个事件,无论是消息、按钮点击还是被拉进群,都以 update 对象形式送达,带有唯一的 update_id。编号按顺序递增。你的代码任务就是获取并处理这些对象。获取方式只有两种,且互斥。
长轮询(long polling)
你的机器人主动问 Telegram:有我的新更新吗?通过 getUpdates 方法实现。“长”的意思是说,服务器不会立刻返回空列表,而是保持连接打开直到指定超时时间(通常 30-60 秒),一旦有事件就立即返回。这既省请求又能近乎即时响应。轮询不需要公网地址,在路由器后也能用,走任何代理都没问题。适合起步阶段和负载不大的机器人。
Webhook(网络钩子)
反过来。你用 setWebhook 方法告诉 Telegram 你服务器的地址,Telegram 主动把每条更新以 POST 请求发到该地址。你不需要轮询。要求:公网域名、HTTPS 证书,以及 443、80、88 或 8443 端口之一。Webhook 扩展性更好,不用花资源等待。
重要提示:代理只影响机器人向 Telegram 发出的请求。Webhook 的入站请求直接到达你的服务器,代理不参与这个环节。所以“Webhook 走代理”在实际中是指:机器人通过代理回复并调用 API 方法,但接收更新用自己的公网地址。
429 Too Many Requests 错误
Telegram 限制请求频率。2026 年的参考值:单个聊天每秒不超过一条消息,单个群每分钟不超过 20 条,一个机器人总计每秒约 30 条。超出时服务器返回 HTTP 状态 429,响应体里的 parameters.retry_after 字段是等待秒数。不能忽略它:不加停顿地重试只会加长封禁时间。
为什么机器人要用代理
原因很实际。第一,固定可预测的出口 IP:服务器多但只需一个外部地址时很方便。第二,按项目分流:每个客户或每个广告系列走独立通道。第三,企业政策要求所有外连必须走网关。移动代理在这里的价值在于稳定性,以及可按计划或链接切换 IP。
第 1 步:创建机器人并获取 Token
本步目标:获取 Telegram Bot API 访问 Token,确认机器人已存在。
- 在手机或电脑上打开 Telegram。
- 在搜索栏输入 BotFather。选择带蓝色认证勾的机器人,假冒的没有。
- 点击 Start 按钮或发送
/start命令。你会看到可用命令列表。 - 发送
/newbot命令。 - BotFather 会问机器人显示名称。输入显示名,比如 Proxy Test Bot。可以包含空格和中文字符。
- 接着会问 username。它必须唯一、用拉丁字母、以
bot结尾,比如proxy_test_2026_bot。如果名字被占用,BotFather 会提示,换一个即可。 - 回复消息里会有一段像
123456789:AAExampleTokenLettersAndDigits的字符串。这就是 Token。完整复制,包括冒号前的数字。 - 在项目文件夹里创建
.env文件,写入一行BOT_TOKEN=你的_token。
注意:永远不要在聊天、截图和公开仓库里泄露 Token。如果 Token 泄露,立刻向 BotFather 发送 /revoke 命令,选择机器人,获取新 Token。旧 Token 立即失效。
先用不带代理的请求试一下
在复杂化之前,先在本机用普通请求验证 Token 可用。在终端执行以下命令,替换成你的 Token:
curl https://api.telegram.org/bot123456789:AAExampleToken/getMe预期响应:以 {"ok":true,"result":{"id":123456789,"is_bot":true,... 开头的 JSON。里面能看到你刚取的机器人 username。
检查:响应中有 "ok":true 和正确的 username。如果返回 "error_code":401,说明 Token 复制有误,检查首尾是否漏字符。
可能遇到的问题
- Username 被占用。加数字或项目缩写,关键是保留 bot 结尾。
- BotFather 不回复。确认打开的是带认证勾的机器人,不是同名仿冒者。
- 404 Not Found 错误。地址里漏了 Token 前的 bot。格式严格为
/bot<TOKEN>/method。
第 2 步:配置代理并验证 API 访问
本步目标:让向 Telegram Bot API 的请求走你的代理,并实际验证,而不是纸上谈兵。
理解代理地址格式
代理用一行字符串描述:协议://用户名:密码@主机:端口。从个人后台取数据。假设分配给你的主机是 proxy-host,HTTP 端口 8080,SOCKS5 端口 1080,用户名 user,密码 pass。那么字符串是:
- HTTP 代理:
http://user:pass@proxy-host:8080 - SOCKS5 代理:
socks5h://user:pass@proxy-host:1080
注意 socks5h 里的字母 h。它表示域名 api.telegram.org 会在代理端解析,而不是在本机解析。这对移动代理是正确做法:DNS 查询和流量走同一条路径。没有 h 时,本地 DNS 出问题会导致请求失败,即使代理本身是好的。
如果密码里有 @、: 或 /,需要编码:@ 变成 %40,冒号变成 %3A,斜杠变成 %2F。否则字符串会被错误解析。
用 curl 验证
- 先查明外部服务通过你的代理看到的是什么 IP。执行:
curl -x http://user:pass@proxy-host:8080 https://api.ipify.org。响应会返回一个 IP。它应该和你的家庭或服务器地址不同。 - 现在对 Telegram Bot API 发同样的请求:
curl -x http://user:pass@proxy-host:8080 https://api.telegram.org/bot123456789:AAExampleToken/getMe。 - SOCKS5 则替换参数:
curl -x socks5h://user:pass@proxy-host:1080 https://api.telegram.org/bot123456789:AAExampleToken/getMe。 - 测量响应时间:在命令末尾加上
-w " 时间: %{time_total}"。移动代理 1-2 秒以内都算正常。
检查:两个请求都返回 "ok":true,且第一条命令返回的 IP 与你自己不同。说明代理路由畅通,Telegram Bot API 可通过它响应。
在 Python 中配置代理
创建 config.py 文件,内容如下,把值替换成自己的:
import os
TOKEN = os.getenv('BOT_TOKEN', '123456789:AAExampleTokenReplaceMe')
PROXY = os.getenv('BOT_PROXY', 'http://user:pass@proxy-host:8080')
PROXIES = {'http': PROXY, 'https': PROXY}
BASE = f'https://api.telegram.org/bot{TOKEN}'字典里的 https 键是必须的,因为 Telegram Bot API 只通过 HTTPS 工作。新手常犯的错误是只写 http,然后奇怪为什么流量直接出去了。
接下来是测试脚本 check.py:
import requests
from config import PROXIES, BASE
ip = requests.get('https://api.ipify.org', proxies=PROXIES, timeout=15).text
print('出口 IP:', ip)
me = requests.get(f'{BASE}/getMe', proxies=PROXIES, timeout=15).json()
print('机器人:', me['result']['username'])运行:python check.py。屏幕上会显示代理 IP 和机器人 username。
建议:如果你不想改已在使用的库的代码,设置环境变量 HTTPS_PROXY=http://user:pass@proxy-host:8080。requests 库和大多数 HTTP 客户端会自动采用它。这是把现有机器人迁到代理上而无需改代码的便捷方法。
在常用框架中配置
- aiogram 3.x:创建会话
AiohttpSession(proxy='http://user:pass@proxy-host:8080'),在创建Bot(token=TOKEN, session=session)时传入。SOCKS5 需要 aiohttp-socks 包。 - python-telegram-bot 21.x:使用
HTTPXRequest(proxy='http://user:pass@proxy-host:8080'),传给ApplicationBuilder().token(TOKEN).request(request)。 - Node.js:用 https-proxy-agent 或 socks-proxy-agent 包创建 agent,传给 HTTP 客户端选项或机器人库构造函数。
可能遇到的问题
- 407 Proxy Authentication Required。用户名或密码错误,或特殊字符未编码。检查后台里的数据。
- Connection refused。端口填错,或把 HTTP 与 SOCKS5 端口搞混了。试另一个端口。
- 请求直接出去了。字典里没有 https 键,或环境变量在另一个终端窗口里设置。
- SSL 错误。不要关闭证书校验。用
pip install -U certifi更新 certifi 包,并检查系统时间。
第 3 步:启动通过代理的长轮询
本步目标:得到一个可运行的机器人,通过代理用 getUpdates 拉取更新并回复消息,不丢也不重复。
如何正确构建轮询循环
逻辑简单,但细节很重要。你用 offset 参数调用 getUpdates,值等于最后处理的 update_id 加一。这样 Telegram 知道之前的更新已被取走,就从自己那边删除。如果忘了 offset,同一条消息会反复到来,机器人会多次回复。
timeout 参数设定服务器保持连接等待事件的秒数。这里开始体现代理的特殊性。任何代理都有空闲连接超时,移动代理通常在 60-120 秒左右。如果轮询超时大于它,代理会在 Telegram 响应之前先断开连接,你得到的是错误而不是更新。安全值是 timeout=50,HTTP 客户端超时 60 秒。客户端超时必须大于轮询超时,否则客户端先掉线。
编写机器人
- 创建
polling.py文件。 - 复制下面的代码。
- 用
python polling.py运行。 - 在 Telegram 里给机器人发任意消息。
import time, requests
from config import PROXIES, BASE
offset = 0
print('轮询已启动,走代理'
while True:
try:
r = requests.get(f'{BASE}/getUpdates', params={'offset': offset, 'timeout': 50}, proxies=PROXIES, timeout=60)
data = r.json()
except requests.RequestException as e:
print('网络错误:', e)
time.sleep(3)
continue
if not data.get('ok'):
print('API 错误:', data)
time.sleep(3)
continue
for upd in data['result']:
offset = upd['update_id'] + 1
msg = upd.get('message')
if msg and 'text' in msg:
requests.post(f'{BASE}/sendMessage', json={'chat_id': msg['chat']['id'], 'text': '收到: ' + msg['text']}, proxies=PROXIES, timeout=15)解释一下这里发生了什么。外层循环永不自行结束。try 块捕获网络错误:代理断开、超时、IP 切换。出错时脚本等三秒再试,而不是崩溃。data.get('ok') 检查捕获 API 层错误。内层循环处理每条更新并立即推进 offset。
检查:控制台出现启动提示,发消息后机器人回复“收到: 你的文本”。连发三条,机器人应恰好回复三次,各一次。用 Ctrl+C 停掉脚本,发一条消息,再启动:机器人会回复漏掉的那条,因为 Telegram 会保存未处理的更新最多 24 小时。
轮询时移动代理的特点
移动代理能换 IP:按定时器或后台的专用链接。IP 切换瞬间,打开的轮询连接会断开。这不是你代码的错误,是网络的正常行为。我们的循环已经对此做好准备:捕获异常、等待、从同一个 offset 继续。不会丢失任何更新。
不过频繁轮换会在日志里制造多余噪音和微延迟。建议:轮询模式的机器人在后台把轮换间隔设为 10 分钟以上,或关闭自动切换,只在真正需要时用链接换 IP。机器人不是爬虫,不需要每分钟都换新地址。
建议:在日志里记录每条更新的时间和 update_id。一周后有人说机器人没回复,你一分钟就能查出消息是否到达代码,还是网络侧的问题。
可能遇到的问题
- 409 Conflict 错误。最常见的。机器人已设置 Webhook,而轮询和 Webhook 不能同时使用。执行
curl -x 你的代理 https://api.telegram.org/botTOKEN/deleteWebhook再重启脚本。第二个原因:跑了两份脚本,关掉多余的。 - 机器人对每条消息回复两次。offset 没推进,或跑了两份机器人。
- 持续 Read timed out。轮询超时大于代理超时。把 timeout 降到 30-40 秒。
- 回复延迟 5-10 秒。用 curl 测代理响应时间。如果通道本身慢,换出口节点或套餐。
第 4 步:配置带 HTTPS 和密钥令牌的 Webhook
本步目标:Telegram 主动把更新发到你的服务器,机器人通过代理回复。这步需要带域名的 VPS,所以如果你目前只有轮询且已满足,可以先到第 5 步,以后再来做。
准备服务器和域名
- 租一台 Ubuntu 的 VPS。记下公网 IP。
- 在域名面板里建 A 记录,比如
bot.example.com,指向服务器 IP。等 DNS 生效,通常 5-30 分钟。用nslookup bot.example.com检查。 - SSH 连上服务器,更新软件包:
sudo apt update。 - 安装 nginx 和 certbot:
sudo apt install nginx certbot python3-certbot-nginx。 - 开放 80 和 443 端口:
sudo ufw allow 80、sudo ufw allow 443。 - 获取免费证书:
sudo certbot --nginx -d bot.example.com。按提示操作,输入邮箱,同意条款。一分钟内证书签发完成。
Telegram 只接受来自受信任机构的有效 HTTPS 证书的 Webhook。certbot 的证书符合要求。自签名证书也可以,但得用 setWebhook 的 certificate 参数上传其公钥部分,麻烦很多。新手用 certbot 更简单。
配置 nginx 作为入口
Nginx 接收来自 Telegram 的 HTTPS 请求,转发给监听本地 8080 端口的 Flask 应用。用 sudo nano /etc/nginx/sites-available/default 打开 certbot 创建的站点配置,在监听 443 的 server 块里加上这个 location:
location /tg/webhook {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_read_timeout 30s;
}保存文件,用 sudo nginx -t 检查语法,再用 sudo systemctl reload nginx 重载。
建议:把 Webhook 路径做得不显眼,比如 /tg/webhook/k8s7d2f。这不是密钥令牌的替代,而是额外一层:随手扫描器找不到你的入口。
编写 Webhook 处理器
在服务器上创建 webhook.py。它接收 Telegram 的 POST,校验密钥头部,通过代理回复用户。call 函数我们下一步写,先用普通 requests.post 带 proxies。
import requests
from flask import Flask, request, abort
from config import PROXIES, BASE
app = Flask(__name__)
SECRET = 'MySecret123'
@app.post('/tg/webhook')
def webhook():
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != SECRET:
abort(403)
update = request.get_json(silent=True) or {}
msg = update.get('message')
if msg and 'text' in msg:
requests.post(f'{BASE}/sendMessage', json={'chat_id': msg['chat']['id'], 'text': '已通过 Webhook 收到'}, proxies=PROXIES, timeout=15)
return 'ok', 200
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080)关键点:X-Telegram-Bot-Api-Secret-Token 头部。如果你在设置 Webhook 时指定了 secret_token,Telegram 会给每个请求加上它。任何缺少正确值的请求都以 403 被拒绝。这样别人就无法给机器人塞假消息。
启动应用:python webhook.py。长期运行以后可以做成 systemd 服务,但验证阶段直接启动就行。
通过代理注册 Webhook
setWebhook 调用本身也走代理,因为它是向 Telegram Bot API 的发出请求。在任何能访问代理的机器上执行:
curl -x http://user:pass@proxy-host:8080 -F "url=https://bot.example.com/tg/webhook" -F "secret_token=MySecret123" -F "max_connections=40" -F "drop_pending_updates=true" https://api.telegram.org/bot123456789:AAExampleToken/setWebhook解释参数。url 是你的处理器地址。secret_token 是 1 到 256 个字符的字符串,由拉丁字母、数字、连字符和下划线组成,必须和代码里的 SECRET 一致。max_connections 是 Telegram 能同时打开多少请求到你,1 到 100,默认 40。drop_pending_updates 是清空积压的更新,避免切换瞬间机器人爆发式回复旧消息。
预期响应:{"ok":true,"result":true,"description":"Webhook was set"}。
用 getWebhookInfo 诊断
这是调试 Webhook 的主要工具。执行:
curl -x http://user:pass@proxy-host:8080 https://api.telegram.org/bot123456789:AAExampleToken/getWebhookInfo看响应里的字段:url 应与你的地址一致,pending_update_count 显示未处理更新的队列长度,last_error_date 和 last_error_message 会在 Telegram 投递失败时出现。发一条测试消息后,错误字段为空就表示完全成功。
检查:给机器人发消息,它回复了“已通过 Webhook 收到”。getWebhookInfo 里没有 last_error_message,pending_update_count 为零。Flask 日志里有 POST /tg/webhook 和 200 的条目。
注意:Webhook 处理器必须快速响应,几秒之内。如果你的代码思考很久,比如做重数据库查询或通过慢代理调用外部服务,Telegram 会认为投递失败并重试。把重活放到后台任务,Webhook 立即返回 200。
可能遇到的问题
- last_error_message: SSL error。证书无效、过期或签发给了别的域名。检查
sudo certbot certificates。 - Connection timed out。443 端口在防火墙或主机商处被关。检查
sudo ufw status和 VPS 面板设置。 - Wrong response from the webhook: 403。代码里的密钥令牌和 setWebhook 时的不一致。检查字母大小写。
- Wrong response from the webhook: 502。Flask 没运行或监听别的端口。检查
ss -tlnp | grep 8080。 - Bad webhook: port not allowed。只能用 443、80、88 或 8443。
第 5 步:处理 429 错误,让请求更稳健
本步目标:写一个函数处理所有 Telegram Bot API 调用,遇到 429 自动等待,网络和代理故障时重试,永远不让机器人崩溃。
为什么不能忽略 429
当你给一千个用户群发时,每秒 30 条的限制瞬间就撞上。Telegram 返回 429 并给出 retry_after。如果继续猛打服务器,消息发不出去,后续响应里的等待时间还会增长。走代理有个细节:Telegram 的限制绑定的是机器人,不是 IP。轮换 IP 无法绕过限制,也不该用来做这事。唯一正确的方式是尊重 retry_after 并控制发送速度。
编写通用封装
在 config.py 或单独的 api.py 里加上这个函数:
import time, requests
from config import PROXIES, BASE
def call(method, payload, retries=6):
for attempt in range(retries):
try:
r = requests.post(f'{BASE}/{method}', json=payload, proxies=PROXIES, timeout=15)
except requests.RequestException as e:
print('网络或代理:', e)
time.sleep(min(2 ** attempt, 30))
continue
if r.status_code == 429:
wait = r.json().get('parameters', {}).get('retry_after', 1)
print('429 Too Many Requests, 等待', wait, '秒')
time.sleep(wait + 0.5)
continue
if 500 <= r.status_code < 600:
print('Telegram 服务器错误', r.status_code)
time.sleep(min(2 ** attempt, 30))
continue
data = r.json()
if not data.get('ok'):
print('API 错误:', data.get('description'))
return data
raise RuntimeError('Telegram Bot API: 重试次数用尽 ' + method)这个函数做了什么。网络错误时按指数等待:1、2、4、8 秒,但不超过 30 秒。这样机器人能熬过代理换 IP 或通道短暂故障。429 时读取 retry_after,加半秒余量后重试。Telegram 侧 5xx 错误也带停顿重试。400 或 403 错误(比如用户屏蔽了机器人)重试无用,所以函数原样返回响应,由你决定后续处理。
提前限速
最好根本别撞到 429。群发时在消息之间加停顿。最简单的办法:每次发送后 time.sleep(0.05),即每秒 20 条,低于总限制。单个聊天间隔不低于一秒。群组每分钟不超过 20 条。
def broadcast(chat_ids, text):
sent, failed = 0, 0
for cid in chat_ids:
res = call('sendMessage', {'chat_id': cid, 'text': text})
if res.get('ok'):
sent += 1
else:
failed += 1
time.sleep(0.05)
print('已发送:', sent, '错误:', failed)建议:保存返回 403 Forbidden: bot was blocked by the user 的响应。从群发名单里删除这类用户。这能减轻负担,也避免触发多余限制,因为失败请求也算数。
测试 429 处理
- 建一个测试群,把机器人拉进去。
- 在该聊天里跑 40 次
call('sendMessage', {...})的循环,不加停顿。 - 观察控制台:几次快速发送后会出现 429 和等待时间的行。
- 确认停顿后发送继续,40 条消息全部送达。
检查:所有消息送达,机器人没异常崩溃,日志里能看到 retry_after 停顿。把 polling.py 和 webhook.py 里的 requests.post 换成 call 函数,让所有 Telegram Bot API 交互走同一个受保护的通道。
可能遇到的问题
- retry_after 巨大,几百秒。你长期无视限制。彻底停止发送,等够指定时间,再降低节奏。
- 刚开始发就 429。另一个进程在用同一 Token。检查是不是旧版机器人还在跑。
- 429 时响应不是 JSON。有些代理返回自己的 HTML 错误页。把 r.json() 包进 try,失败时固定等 5 秒。
第 6 步:高负载项目的进阶配置
本步目标:让机器人应对增长:多机器人走多代理、发送队列、本地 Bot API 服务器和合理轮换。新手可以跳过,等用户过千再回来看。
多个机器人走不同代理
营销人员常在一台服务器上运营十几个不同项目的机器人。正确的架构:每个机器人有自己的 proxies 字典和独立的 requests.Session()。会话复用 TCP 连接,减轻代理负担,请求速度提升 2-3 倍。配置存成列表:Token、代理地址、获取更新模式。一个机器人一个进程比一个进程管所有更好调试。{
用发送队列代替直接调用
群发上万人时,从主代码直接调用就行不通了。建一个队列:Redis 或至少数据库里一张表,字段有 chat_id、text、status、attempts。单独的 worker 取任务并调用 call 函数控制速度。遇到 429 时 worker 休眠,而不阻塞 Webhook 接收。这样群发在后台进行时,机器人仍能响应用户命令。2026 年 Telegram Bot API 允许付费机器人通过 allow_paid_broadcast 参数把限制提到每秒 1000 条,但要消耗 Stars,所以对多数项目来说,每秒 20-25 条的队列仍是最优解。
本地 Bot API 服务器
Telegram 公开了 Bot API 服务器源码,可以自己跑。你的代码不再访问 api.telegram.org,而是访问 localhost,本地服务器再与 Telegram 通信。好处:文件上传上限 2 GB 而非 50 MB,Webhook 可用任意端口且内网无需 HTTPS,部分限制取消。缺点:代理得在本地服务器层面配置,而不是机器人代码里。适合有 DevOps 能力的团队,起步阶段没必要。
IP 轮换与 Webhook
用 Webhook 时代理换 IP 几乎无感:每次 sendMessage 调用都很短,切换瞬间最多影响一个请求,call 封装会重试。所以 Webhook 模式下的轮换可以比轮询更频繁。不过频繁切换没意义:Telegram Bot API 不按 IP 限制请求,限制绑定在 Token 上。轮换频率从你基础设施的角度定,而不是为 API。
不搭专门系统也能做健康监控
一开始就该有的最低配置:每分钟调用 getWebhookInfo,把 pending_update_count 和 last_error_message 写进日志。如果队列连续三次测量都在增长,说明处理器跟不上。轮询模式下记录最后一次成功 getUpdates 的时间:超过两分钟说明连接卡死,重启进程。这足以让你比客户先发现问题。
建议:不仅记录错误,还记录每次通过代理向 Telegram Bot API 请求的耗时。平均响应时间从 0.3 秒慢慢涨到 2 秒,会在机器人开始丢消息的前几天就预警通道退化。
结果验证:成品检查清单
逐条过一遍。每条都打勾,机器人才算准备好服务真实用户。
检查清单
- 带 -x 参数的 curl 通过代理调用 getMe 返回
"ok":true。 - check.py 脚本显示代理 IP,而不是你自己的。
- 轮询回复消息一次,无重复。
- 停止再重启轮询后,漏掉的消息被处理。
- 强制在代理上切换 IP 后,轮询 3-5 秒内自动恢复。
- Webhook:getWebhookInfo 显示你的 url、pending_update_count 为零、last_error_message 为空。
- 不带密钥头部的 Webhook 请求返回 403。
- 快速向单个聊天发 40 条消息不崩溃,日志里有 retry_after 停顿。
- Token 和代理数据在 .env 里,不在代码里。
如何整体测试
- 按选定模式启动机器人。
- 用三个不同账号各发两条消息给它。
- 确认收到六条回复,每条消息各一次。
- 在代理后台点换 IP 链接,立刻再发一条消息。
- 机器人应在 10 秒内回复。
- 跑第 5 步的 429 测试。
- 检查日志:没有未处理的异常和堆栈。
成功指标
机器人回复消息时间在 2 秒内。所有重试后向 Telegram Bot API 的失败请求占比低于 0.1%。一天内零重复。峰值时段 getWebhookInfo 的 pending_update_count 不超过十。如果指标都达标,恭喜:你搭好了一套可靠的方案,够用很多个月。
常见错误及解决方案
getUpdates 时报 409 Conflict
原因:机器人设置了 Webhook,或跑了两份轮询实例。解决:通过代理调用 deleteWebhook,确认只有一个进程在跑。用 ps aux | grep polling 检查。
机器人对每条消息回复两次
原因:offset 没递增,或同一 Token 在不同服务器上跑了两份。解决:检查 offset = update_id + 1 这行,停掉多余实例。Webhook 模式确认 nginx 没把请求重复发给两个后端。
407 Proxy Authentication Required 错误
原因:代理凭据错误,或密码里特殊字符没编码。解决:重新核对后台里的用户名密码,把密码里的 @、: 和 / 编码,如果套餐支持 IP 白名单认证也可以试试。
每 50-60 秒 Read timed out
原因:轮询超时大于或等于代理空闲超时。解决:把 getUpdates 的 timeout 降到 30-40 秒,客户端超时比它多 10 秒。
Webhook 已设置但更新不来
原因:端口关闭、证书无效,或处理器没返回 200。解决:看 getWebhookInfo 里的 last_error_message,那是精确诊断。从另一台电脑执行 curl -I https://bot.example.com/tg/webhook 检查。
Wrong response from the webhook: 403 Forbidden
原因:代码里的密钥令牌与 setWebhook 时传的不一致。解决:用与代码相同的值重新设置 Webhook。记住 setWebhook 带新参数会完全替换之前的设置。
小负载下持续 429
原因:机器人向同一聊天发送频率超过每秒一次,比如回复一条命令时连发多条。解决:把回复合并成一条,用 editMessageText 代替新消息来更新进度,给同一 chat_id 的发送之间加停顿。
流量绕过代理直连
原因:proxies 字典里没有 https 键,环境变量对进程不可见,框架没采用配置。解决:用发送消息的同一份代码请求 api.ipify.org 检查出口 IP。别假设,要实际验证。
通过代理请求时 SSL: CERTIFICATE_VERIFY_FAILED
原因:根证书集过时或系统时间不对。解决:更新 certifi,同步时间。永远不要用 verify=False 关闭证书校验:这会让携带 Token 的流量有被替换的风险。
FAQ:配置常见问题
起步选轮询还是 Webhook?
轮询。它在哪里都能跑,不需要域名和证书,以后一小时内就能切到 Webhook。Webhook 适合机器人服务数千用户,或已经运行在有 HTTPS 的服务器上时使用。
能用同一个代理服务多个机器人吗?
可以。Telegram Bot API 的限制绑定 Token,不绑 IP。从 API 角度看,十个机器人走一个代理互不干扰。唯一限制是代理本身的带宽,对文本机器人来说绰绰有余。
Webhook 和回复都必须走代理吗?
Webhook 的入站请求直接到你的服务器,按定义无法走代理。只有出站调用走代理:sendMessage、setWebhook、getFile 等方法。这是正常且唯一可行的方案。
怎么确认请求确实走了代理?
在同一份代码里用相同 proxies 设置请求 https://api.ipify.org,与你的真实 IP 对比。另外可以看代理后台的流量统计:机器人运行时计数器应该增长。
机器人运行时代理换 IP 怎么办?
如果你用了本指南的代码,什么都不用做。轮询会捕获连接断开并从保存的 offset 继续。call 函数会重试失败的请求。唯一建议:轮询模式别把轮换设得比几分钟更频繁。
Telegram Bot API 用 SOCKS5 还是 HTTP 代理?
对机器人来说差别不大,两种都行。HTTP 代理配置更简单,所有客户端都支持,不用额外包。当你希望用 socks5h 方案确保 DNS 在代理端解析时,SOCKS5 更方便。选你在其他项目里已在用的即可。
发多少消息才不会撞 429?
参考值:私人聊天每秒至多 1 条,群组每分钟至多 20 条,总计每秒 25-30 条。群发按每秒 20 条规划,并务必处理 retry_after,因为 Telegram 高负载时限制可能临时降低。
怎么安全地把已在运行的机器人迁到代理?
先用 curl 通过代理测 getMe。然后加 HTTPS_PROXY 环境变量或在代码里配置 proxies,用测试 Token 跑机器人。全部验证通过后再切正式 Token。把旧配置留在手边以便回滚。
怎么撤销 Webhook 回到轮询?
通过代理调用一次 deleteWebhook。如果想保留积压的更新给轮询,不要传 drop_pending_updates。之后启动 polling.py,机器人会接上队列。
能给一个机器人设多个 Webhook URL 吗?
不能,一个机器人只有一个 Webhook。要分散负载,就在唯一的 URL 后面放 nginx 负载均衡,把请求分给多个应用实例。对 Telegram 来说这只是一个入口。
结语
来总结一下你完成的工作。你创建了机器人、拿到了 Token,学会了用 curl 和 Python 验证代理,确认了向 Telegram Bot API 的流量走了正确的路径。你搭好了稳健的长轮询循环,能扛住 IP 切换且不重复消息。你配好了带真实 HTTPS 证书的 Webhook,并用密钥令牌保护它。最有价值的是:你写了一个函数,在 429 时尊重 retry_after,网络故障时重试,把挑剔的通道变成可靠的。
下一步做什么。把机器人做成 systemd 服务,服务器重启后自动拉起。把 Token 和代理地址放到生产机器的环境变量里。加一个简单的响应时间日志,每周看一次。如果用户多了,就上进阶章节里的发送队列。
往哪发展。研究 Telegram Bot API 的内联按钮、支付和小程序方法,它们能给机器人打开营销和销售的全新场景。掌握 aiogram 或 python-telegram-bot 异步框架,它们会接管轮询和重试的琐事,而你已经明白它们底层在做什么。最重要的是:别怕在测试机器人上做实验。每一个你亲手抓到并修复的 429 或 409,都让你比任何现成模板更强。你一定能做到。