ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Telegram Bot API从原理到实战:从requests调用到接入AI大模型

2026/10/4 7:37:16 拓冰建站 浏览量
Telegram Bot API从原理到实战:从requests调用到接入AI大模型 这两天好几个朋友找我说想搞一个 Telegram Bot有的想接 AI 大模型做个私人助理有的想给群里放个自动回复机器人还有的想把通知推送到自己手机。我每次都会先问一句你搞清楚 Telegram Bot API 这几个字母是什么意思了吗不是看不起人而是很多教程一上来就贴代码贴完就跑等你真遇到api error: 400的时候就懵了。这篇我就把 Telegram Bot API 从原理到实战完整过一遍包含用 requests 裸调接口、上 python-telegram-bot 框架、再把 DeepSeek / Grok 这类 AI 接口接进去。适合完全没接触过 Bot 开发的初学者也适合写过几个脚本但一直没搞懂轮询机制的老哥。整篇以实操为主代码直接能跑踩过的坑也都会列出来。1. 准备工作与核心概念1.1 什么是 Telegram Bot API能干什么Telegram Bot API 说白了就是一组 HTTP 接口你的服务端代码通过 HTTPS 请求去操作一个机器人账号让机器人收发消息、处理指令、发文件、做键盘按钮甚至拉群管人。官方文档地址是https://core.telegram.org/bots/api所有方法都是https://api.telegram.org/bottoken/方法名这种格式。这东西能干的事比大多数人想象中多。最简单的就是消息推送比如服务器告警、定时任务结果、爬虫异常通知直接往你的 chat 里丢一条文本。再复杂一点可以做交互机器人用户在对话框里发/start或者输入文字你的程序处理完回一句。配合 Inline Keyboard 还能做按钮菜单比如“查天气”、“签到”、“点歌”。如果你有 AI API 的 key就变成了一个带大脑的私人助理这也是现在最热门的玩法。适合谁来用第一类是产品技术人想低成本做通知和客服入口第二类是搞 AI 应用的人想给大模型套一个聊天前端第三类是普通玩家想给自己的群放点小工具。不管你属于哪类核心要学的东西都一样拿到 token、搞懂 update 怎么来、发消息怎么发。1.2 用 BotFather 拿到那个 Token要操作机器人先得有一个身份凭证就是这个 token。整个过程不需要写代码在 Telegram 里找BotFather这是官方机器人负责创建和管理所有机器人。操作路径很简单找到 BotFather 后发/start再发/newbot它会先要你给机器人起一个显示名称这个随便填比如“我的小助理”。然后要一个用户名这个必须全局唯一而且必须以bot结尾比如my_assistant_bot。提交成功后会返回一段 token长这样1234567890:AAEabcdefghijklmnopqrstuvwxyz-ABCDEFGtoken 分两部分冒号前是机器人数字 ID冒号后是一串密钥。后续所有的 API 调用都靠它相当于机器人的密码。如果你忘了 token可以找 BotFather 发/mybots选中对应机器人进入 API Token 菜单查看或重置。这里重点提醒一句token 一旦泄露任何拿到它的人都能控制你这个机器人轻则乱发消息重则被拿去发垃圾内容导致封号。所以代码里永远别写死 token用环境变量存。1.3 先搞懂几个关键概念chat_id、offset、长轮询与 Webhook很多教程上来就让你复制代码但几个核心名词不讲出了问题你根本不知道在哪查。我这里用最直白的方式解释一遍。chat_id每一个跟机器人聊天的会话都有唯一 ID。私聊时它是一个整数比如123456789群聊时通常是个负数比如-1001234567890。你给机器人发消息机器人收到的 update 里会带上message.chat.id回复时把消息发到对应 chat_id 就行。getUpdates 与 offset机器人不会“主动”收到消息而是你调用getUpdates去拉取。Telegram 会把你机器人收到的所有新事件私聊、群聊、按钮回调等都存成一个队列每次调用getUpdates就从这个队列里取最新的一批。为了避免重复取你要用offset参数告诉服务器“我已经处理到哪一条了”。规则是把当前批次最大的update_id 1作为下一次请求的 offset。长轮询与 Webhook这是两种接收消息的方式。长轮询是程序主动循环请求getUpdates连接保持一段时间有消息立即返回没有就等一会儿Webhook 则是你提供一个 HTTPS 回调地址Telegram 服务器一有消息就主动 POST 给你。开发调试阶段基本都用长轮询零成本、不需要公网。正式线上部署、对实时性要求高的场景才考虑 Webhook。2. 不用库直接用 requests 调 Bot API2.1 怎么发第一条消息getMe 与 sendMessage我建议每个人都先用最原始的方式调一次接口不引入任何框架这样你能真正理解 API 的工作原理。先装一个requests库然后写几行代码验证你的 token 是否可用。import requests TOKEN 1234567890:AAEabcdefghijklmnopqrstuvwxyz-ABCDEFG API fhttps://api.telegram.org/bot{TOKEN} # 验证 token r requests.get(f{API}/getMe, timeout10) print(r.json())如果返回{ok: true, result: {id: ..., username: ...}}说明 token 有效。getMe是官方提供的最轻量的接口相当于握手测试。接下来用sendMessage给自己发一条消息。CHAT_ID 123456789 # 改成你的 chat_id r requests.post( f{API}/sendMessage, json{chat_id: CHAT_ID, text: 你好我是机器人}, timeout10, ) print(r.json())这里的关键参数只有两个chat_id发给谁text发什么内容。注意CHAT_ID必须是你自己的数字 ID。怎么拿给机器人先发一条消息然后调用一次getUpdates在返回的 JSON 里找message.chat.id。这一步做完你已经具备了一个最基础的 Bot 雏形能收发消息。2.2 用 getUpdates 做长轮询offset 机制与处理光能发消息不算机器人能收到消息并自动回复才算。接收消息的唯一途径是getUpdates。第一次调用它你会看到一大堆原始 JSON这就是所谓的 update。r requests.get(f{API}/getUpdates, timeout30) print(r.json())返回结构大概是{ ok: true, result: [ { update_id: 10001, message: { message_id: 3, from: {id: 123456789, is_bot: false, first_name: Foo}, chat: {id: 123456789, type: private}, text: 你好 } } ] }update_id是每条事件的唯一自增编号message.text是用户发的文本。你如果直接把这段代码反复跑会发现同一个 update 被重复返回了无数次因为服务器不知道你处理到哪了。解决办法就是传 offset每次处理完这批 update把最后一个update_id 1存下来下次带过去。def get_updates(offsetNone): params {timeout: 30} if offset is not None: params[offset] offset resp requests.get(f{API}/getUpdates, paramsparams, timeout35) return resp.json() last_update_id 0 while True: data get_updates(offsetlast_update_id 1) if data.get(ok): for upd in data[result]: message upd.get(message) if message and text in message: chat_id message[chat][id] text message[text] send_message(chat_id, f你说了{text}) last_update_id max(last_update_id, upd[update_id])这里有一个关键点offset应该传last_update_id 1意思是“从这个编号之后开始取”。为什么要用max而不是直接赋值因为 Telegram 偶尔会把 update 乱序返回直接赋值容易丢消息。等所有消息都处理完才更新 offset如果中途异常退出下次还能重新拿到这批消息保证不丢。2.3 一个最简自动回复 Bot 的完整示例把上面的代码拼起来就是一个能复读的机器人。完整逻辑是启动后死循环拉取消息用户说什么它回什么。代码量不超过三十行但它已经把 Telegram Bot 最核心的“收发”链路完整跑通了。import requests import time TOKEN 1234567890:AAEabcdefghijklmnopqrstuvwxyz-ABCDEFG API fhttps://api.telegram.org/bot{TOKEN} def send_message(chat_id, text): requests.post(f{API}/sendMessage, json{chat_id: chat_id, text: text}, timeout10) last_update_id 0 while True: try: data requests.get( f{API}/getUpdates, params{offset: last_update_id 1, timeout: 30}, timeout35, ).json() if data.get(ok): for upd in data[result]: message upd.get(message) if message and text in message: chat_id message[chat][id] send_message(chat_id, message[text]) last_update_id max(last_update_id, upd[update_id]) except Exception as exc: print(请求异常, exc) time.sleep(1)跑起来之后在 Telegram 里给你的机器人发一句“test”它会把“test”弹回来。这就是最原始的 Bot。这个版本的缺点很明显全部是全局变量、没有消息类型区分、无法处理并发、代码一多就乱。但它能让你直观理解 API 每次请求都带 token、依赖 offset 防重复背后的逻辑。理解之后我们再用框架把工程问题解决掉。3. 上框架用 python-telegram-bot 写一个正经 Bot3.1 安装与基础模板如果你自己用 requests 裸写过一遍长轮询再看python-telegram-bot框架会顺很多因为它把你手动做的事情全部封装好了。这个库是目前 Python 生态里维护最活跃、口碑最好的 Telegram Bot 框架支持异步、Handler 注册、键盘、文件上传等高级功能。安装很简单pip install python-telegram-bot21.6注意版本v20 和 v21 的 API 差异不小外面很多教程还是 v13 的同步写法直接复制到新版跑不起来。我这里以 v21 为准。最小可运行模板from telegram.ext import Application, CommandHandler, MessageHandler, filters import os TOKEN os.getenv(BOT_TOKEN) async def start(update, context): await update.message.reply_text(你好我是机器人) async def echo(update, context): await update.message.reply_text(update.message.text) def main(): app Application.builder().token(TOKEN).build() app.add_handler(CommandHandler(start, start)) app.add_handler(MessageHandler(filters.TEXT ~filters.COMMAND, echo)) app.run_polling() if __name__ __main__: main()Application就是整个应用的核心负责接收 update 并分发。add_handler注册处理函数每个 handler 对应一类消息。CommandHandler处理斜杠命令比如/startMessageHandler处理普通文本消息还能用过滤器细分比如filters.TEXT表示纯文本、filters.PHOTO表示图片、~filters.COMMAND表示排除命令。run_polling()一启动框架就自动用长轮询拉消息了你不需要手动处理 offset。3.2 用命令和消息处理器实现交互框架最大的价值是让你把精力放在业务逻辑上而不是底层收发。比如实现一个“/start 弹说明、文本消息走 AI 回复、点击按钮触发回调”的交互代码依然非常清晰。from telegram import Update, ReplyKeyboardMarkup from telegram.ext import Application, CommandHandler, MessageHandler, CallbackQueryHandler, ContextTypes, filters async def start(update, context): keyboard [[关于我, 帮助]] reply_markup ReplyKeyboardMarkup(keyboard, resize_keyboardTrue) await update.message.reply_text(欢迎使用选择一个功能, reply_markupreply_markup) async def handle_text(update, context): text update.message.text if text 关于我: await update.message.reply_text(我是一个 Telegram Bot 示例) elif text 帮助: await update.message.reply_text(发送任意消息给我即可) else: await update.message.reply_text(f你发了{text}) def main(): app Application.builder().token(TOKEN).build() app.add_handler(CommandHandler(start, start)) app.add_handler(MessageHandler(filters.TEXT ~filters.COMMAND, handle_text)) app.run_polling() if __name__ __main__: main()ReplyKeyboardMarkup是出现在输入框上方的快捷按钮适合做菜单InlineKeyboardMarkup是消息里内联的按钮适合做卡片式交互。如果你做 AI Bot常见套路是用户发文字 - 你先把“正在思考…”发出去 - 调模型接口 - 把结果发回来。框架的update.message.reply_text会自动使用当前会话的 chat_id省去手动传参。3.3 长轮询与 Webhook 该怎么选很多人第一次部署 Bot 都会纠结这个问题我直接给结论开发调试和中小流量用长轮询正式生产且对延迟敏感用 Webhook。对比项长轮询 PollingWebhook消息获取方式程序主动请求getUpdatesTelegram 向你的 HTTPS 地址 POST是否需要公网不需要本地/内网即可需要公网可访问的 HTTPS 地址证书要求无需要 HTTPS 证书部署简单度简单一个进程跑起来就行需要 Nginx / Caddy / 云函数等配合适用场景学习、开发、个人机器人线上服务、低延迟要求用 python-telegram-bot 切换 Webhook 很简单把run_polling()换成app.run_webhook( listen0.0.0.0, port8443, url_pathTOKEN.split(:)[0], webhook_urlhttps://yourdomain.com:8443/1234567890, )url_path填 token 前缀防止别人猜到路径刷请求。如果没有公网服务器就别碰 Webhook长轮询完全够用。实际经验是个人项目、群管理机器人跑在一台小机器上长轮询连续稳跑一两个月没有任何问题。4. 实战把 AI 大模型接进 Bot4.1 接入前先确认 API 的 base_url 和 model 名现在大家玩 Bot很大一部分是为了把 AI 大模型接进去。不管你是用 DeepSeek、智谱 GLM 还是 Grok流程基本都是同一个套路拿到 API Key - 确认接口地址和模型名 - 调用 Chat Completions 接口 - 把模型返回的文本通过 Bot 发出去。最容易踩的坑就是模型名。不同平台的模型名差异巨大你按网上教程复制一个 model 参数很可能报api error: 400 the supported api model names are deepseek-flash, deepseek-v4意思是当前这个服务商只接受deepseek-flash、deepseek-v4而你传了什么别的名字。这种错误很容易闹乌龙因为官方 DeepSeek API 的模型名其实是deepseek-chat和deepseek-reasoner。为什么对不上因为对方很可能走的是第三方兼容服务模型名做了自定义。我处理这类问题的方法是看平台文档或者直接请求/models接口把可用模型列表拉出来。以 DeepSeek 官方接口为例用 curl 验证curl https://api.deepseek.com/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_API_KEY \ -d { model: deepseek-chat, messages: [{role: user, content: 你好}], max_tokens: 100 }这个拿到了 200再往下写代码。另外还有一类错误是你接的工具调用Function Calling没通过 schema 校验报错形如api error: 400 invalid schema for function artifact。这种一般是函数命名或者参数 JSON Schema 不合法比如函数名里带了特殊字符或者正则表达式写得不规范把函数名改成纯字母数字下划线、参数结构严格按 JSON Schema 写基本能解决。4.2 用 OpenAI 兼容接口把 Bot 和大模型串起来现在主流大模型厂商的 API 基本都是 OpenAI 兼容格式所以我推荐直接用openai这个 Python SDK 统一调用别用各家自己的 SDK减少心智负担。pip install openai完整示例用户给机器人发一条消息机器人转发给 DeepSeek模型返回后回填给用户。这里我用AsyncOpenAI因为 python-telegram-bot 是异步框架如果耗时的 API 调用用了同步 requests会阻塞整个事件循环消息一多就卡死。import os from openai import AsyncOpenAI from telegram import Update from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes TOKEN os.getenv(BOT_TOKEN) DEEPSEEK_API_KEY os.getenv(DEEPSEEK_API_KEY) DEEPSEEK_BASE_URL os.getenv(DEEPSEEK_BASE_URL, https://api.deepseek.com) client AsyncOpenAI(api_keyDEEPSEEK_API_KEY, base_urlDEEPSEEK_BASE_URL) SYSTEM_PROMPT 你是一个乐于助人的私人助理。 async def start(update, context): await update.message.reply_text(你好我是 AI 助理直接发消息给我就行。) async def handle_message(update, context): user_text update.message.text await update.message.reply_text(正在思考请稍候...) try: resp await client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_text}, ], max_tokens1024, timeout30, ) answer resp.choices[0].message.content await update.message.reply_text(answer) except Exception as exc: await update.message.reply_text(f调用 AI 接口出错{exc}) def main(): app Application.builder().token(TOKEN).build() app.add_handler(CommandHandler(start, start)) app.add_handler(MessageHandler(filters.TEXT ~filters.COMMAND, handle_message)) app.run_polling() if __name__ __main__: main()如果你要接的不是 DeepSeek而是 Grok、GLM、Kimi 这些只需改base_url和model两个参数。比如 xAI 的接口平台改一下地址模型名换成对应的 grok 型号其余代码不动。AsyncOpenAI兼容性足够好这省了我在多个 SDK 之间来回切换的时间。4.3 超时、并发和错误处理接 AI 接口的 Bot 和普通 Bot 最大的不同在于AI 接口慢。DeepSeek 生成几百字可能就要好几秒用户在 Telegram 上会焦躁所以要做两件事先发一个“正在输入”的聊天状态请求设置超时避免无限卡死。from telegram.constants import ChatAction async def handle_message(update, context): await context.bot.send_chat_action( chat_idupdate.effective_chat.id, actionChatAction.TYPING, ) # 然后调用 AI 接口关于超时我习惯给AsyncOpenAI的调用单独设置 reasonable 的值比如timeout30不要依赖 SDK 默认的无限等待。如果你遇到api call failed after 3 retries: http 500: llama-server process has terminated这种错误说明服务端不稳定大概率是对方的推理服务挂了此时要做的是指数退避重试而不是硬刚。连续失败就返回一个友好的提示别让用户卡着。并发也是一个隐藏问题。如果用户接连发多条消息你的 Bot 会同时发多个 AI 请求很容易触及 API 限流触发 429。我的做法是给每个 chat 加一个简单的互斥锁或者直接用context.application的全局字典做队列。小规模用户量其实不用太担心个人助理场景一天几百条消息绝大多数平台都能扛住。5. 常见报错与排查技巧5.1 多个实例抢消息409 Conflict这是长轮询开发中最经典的错误。现象是你本地跑着一个run_polling()然后测试服务器上又部署了一个同样的 Bot随后日志里出现Conflict: terminated by other getUpdates requestTelegram 不允许同一个 token 同时被两个轮询实例拉取消息。如果你开了 Webhook 又同时调getUpdates也会出现类似问题。排查思路很直接先确认没有其他进程占用这个 token再确认 Webhook 没有启用。你可以调用getWebhookInfo看一眼当前状态curl https://api.telegram.org/bottoken/getWebhookInfo返回里如果url非空说明还有 Webhook 挂着执行deleteWebhook清掉再跑轮询。这个错误我遇到过好几次每次都是因为本地调试脚本忘记退出又开了新脚本。5.2 常见报错速查表把这些年遇到的 Bot 相关报错攒了一张表从 Telegram API 错误到大模型 API 错误都有排查时对着看能省很多时间。报错信息常见原因处理方法404 Not Found或Not Foundtoken 错误或失效检查 token用 getMe 验证必要时找 BotFather 重置400 Bad Request: chat not foundchat_id 不对或机器人从未与这个会话接触确认 chat_id群聊要先把机器人拉进群409 Conflict: terminated by other getUpdates多个轮询实例同时运行只保留一个实例检查 Webhook 状态429 Too Many Requests请求频率太高降低频率读取retry_after字段等待后再发api error: 400 content exists risk发的内容触发服务方内容审核调整提示词或消息内容不要硬冲api error: 400 invalid schema for function artifact函数名或 JSON Schema 不合法函数名用纯字母数字下划线Schema 严格校验api error: 400 the supported api model names are...model 参数名填错去平台文档查具体模型名connection lost mid-response网络中断或对方服务读取超时先 curl 验证接口稳定性加大 timeout加重试http 500 llama-server process has terminatedAI 推理服务进程崩溃指数退避重试或临时换模型5.3 Token 安全与防滥用最后聊一个很多人忽视的运维问题。Bot token 一旦泄露后果比想象中严重。我曾经见过有人在 GitHub 上公开了 token几分钟内机器人就被别人拉去刷广告。如果你的 token 泄露了马上找 BotFather 发/revoke它会废弃旧 token 并生成新的然后去代码和部署环境里替换。一些我能想到的可行习惯token 和环境变量放一起用os.getenv读取不写进代码仓库。Webhook 路径里带上 token 前缀避免暴露接口。群里用机器人时注意隐私模式如果不需要读取群里所有普通消息保持默认即可如果要做群内 AI 客服找 BotFather 关闭 privacy mode或者通过管理员权限做白名单。不要做群发骚扰、赌博、擦边内容等违反平台条款的功能封号是小事被举报到服务商那就麻烦了。AI 接口的 API Key 也要谨慎保管很多平台超出免费额度后扣费速度很快建议设置消费上限或用量监控。我自己现在的日常用法是一个 Bot 负责接收消息另一个脚本定时推送任务摘要再到一个方向是接 DeepSeek 做群里的问答机器人。反正一套 API 链路搞清楚之后改改就能复用。最后分享一个我自己的习惯不管接的什么 AI 模型第一件事永远是用 curl 把 Chat Completions 接口调通确认 base_url、model、鉴权都没问题再写机器人代码。机器人只是套了一层壳真正的问题大多出在 API 参数和网络超时上。先从小样本验证再逐步放开能少踩很多坑。