Telegram机器人如何设置Webhook接收消息:从零到实战的完整指南

本文深入讲解Telegram机器人Webhook的工作原理,提供从创建机器人、获取令牌到配置Webhook并处理消息的完整步骤,并附上Node.js与Python代码示例及常见问题排查方法,助你快速构建实时交互机器人。

阅读提示建议先浏览文章结构,再按需深入阅读具体段落。

在Telegram机器人开发中,Webhook机制是实现服务器实时推送消息的关键。相比轮询(Polling),Webhook能让Telegram在机器人收到新消息时主动向你的服务器发送HTTPS请求,从而显著降低延迟和资源消耗。本教程将手把手教你如何从零配置Webhook,并提供可直接运行的代码示例,帮助你快速上手。

一、Webhook核心概念与工作原理

Webhook是一种反向API回调:Telegram服务器作为客户端,你的服务器作为服务端。当用户向机器人发送消息时,Telegram会向预先设定的URL地址发送一个包含消息数据的JSON对象。开发者只需在服务器上监听该URL并处理收到的数据即可。

与GetUpdates轮询相比,Webhook具有以下优势:

  • 实时性高:消息即时推送,无需客户端轮询间隔。
  • 资源占用低:服务器只需处理有消息时的请求。
  • 支持双向推送:便于实现主动发送消息(如定时通知)。

但使用Webhook必须满足两个基本要求:

  • 服务器必须拥有公网IP且能通过HTTPS访问;
  • 需配置有效的SSL证书(Telegram不支持自签名证书,但支持通过Linux Foundation签发的免费证书)。

二、准备工作:创建机器人与获取令牌

所有Telegram机器人都需要先通过BotFather创建。步骤如下:

  1. 在Telegram中打开 @BotFather,发送 /newbot 命令。
  2. 按照提示设置机器人显示名称和用户名(用户名必须以 bot 结尾,如 MyRssBot)。
  3. 创建成功后,BotFather会返回一个HTTP API令牌(形如 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)。请立即保存并保持机密,该令牌是控制机器人的唯一凭证。

三、配置Webhook的三种方法

获取令牌后,可通过以下任一方式设置Webhook地址。

方法一:使用浏览器直接访问URL(最快速)

在浏览器中打开以下API地址(请替换自己的令牌和URL):

https://api.telegram.org/bot<你的令牌>/setWebhook?url=https://yourdomain.com/webhook

若设置成功,页面会返回 {"ok":true,"result":true,"description":"Webhook was set"}

方法二:使用curl命令(服务器端推荐)

curl -F "url=https://yourdomain.com/webhook" "https://api.telegram.org/bot<你的令牌>/setWebhook"

方法三:编写代码脚本动态设置

在您的后端代码中调用API接口,以便在应用启动时自动注册。

// Node.js 示例
const token = '你的令牌';
const webhookUrl = 'https://yourdomain.com/webhook';
const res = await fetch(`https://api.telegram.org/bot$/setWebhook?url=$`);
const data = await res.json();
console.log(data);

四、Webhook服务器的实现(Node.js示例)

创建Webhook端点,接收Telegram推送的Update对象。以下为使用Express的完整示例:

const express = require('express');
const app = express();
app.use(express.json());

const BOT_TOKEN = '你的令牌';
const TELEGRAM_API = `https://api.telegram.org/bot$`;

app.post('/webhook', (req, res) => {
  const update = req.body;
  const { message } = update;
  if (message && message.text) {
    console.log('收到消息:', message.text);
    // 这里可以调用API回复消息
    // fetch(TELEGRAM_API + '/sendMessage', {
    //   method: 'POST',
    //   headers: { 'Content-Type': 'application/json' },
    //   body: JSON.stringify({ chat_id: message.chat.id, text: '你好!' })
    // });
  }
  res.sendStatus(200); // 必须尽快响应200,否则Telegram会重试
});

app.listen(3000, () => console.log('Webhook server listening on port 3000'));

关键点:一定要返回200状态码,否则Telegram会按指数退避策略重试发送同一更新,导致重复处理。

五、Webhook服务器的Python实现(Flask)

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)
BOT_TOKEN = '你的令牌'
TELEGRAM_API = f'https://api.telegram.org/bot'

@app.route('/webhook', methods=['POST'])
def webhook():
    update = request.get_json()
    if 'message' in update:
        chat_id = update['message']['chat']['id']
        text = update['message'].get('text','')
        print(f'收到消息: ')
        # 回复消息
        requests.post(f'/sendMessage', json={'chat_id': chat_id, 'text': '收到!'})
    return 'OK', 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=443, ssl_context=('cert.pem', 'key.pem')) # 本地测试时用,生产建议用Nginx反代

六、SSL证书与HTTPS部署要点

Telegram要求Webhook必须使用HTTPS。常见解决方案:

  • 使用云服务器厂商提供的免费证书(如Let's Encrypt)。
  • 将Nginx作为反向代理,配置好SSL后把请求转发到本地应用的HTTP端口。
  • 如果使用Python/Node开发,也可直接配置证书,但更推荐Nginx统一处理。

示例Nginx配置:

server {
    listen 443 ssl;
    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 {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

七、验证Webhook是否设置成功

使用 getWebhookInfo 方法检查状态:

https://api.telegram.org/bot<令牌>/getWebhookInfo

响应中会包含 url have_custom_certificate pending_update_count last_error_message 等字段,方便调试。

八、常见问题排查

1. 设置Webhook时报错“Bad Request: can't use getUpdates method while webhook is active”

原因是当前有正在运行的轮询程序。必须先删除或停用所有通过getUpdates获取更新的进程,再设置Webhook。可先调用 deleteWebhook 清空旧配置。

2. Webhook一直收不到消息

使用 getWebhookInfo 查看 last_error_message,常见错误为“Wrong URL”或“SSL certificate error”。检查URL是否公网可访问、证书是否有效。

3. 重复收到相同消息

可能是因为没有及时返回200或处理时间超过请求超时。确保你的处理逻辑尽量轻量,或先返回200再异步处理业务逻辑。

4. 如何关闭Webhook恢复轮询

调用 /deleteWebhook?drop_pending_updates=true,然后使用getUpdates即可。

总结

Webhook机制是开发Telegram机器人时必须掌握的核心技能。通过本指南,你已经学会了从创建Bot到配置SSL、编写服务器代码以及排查常见问题。实际项目中,还需结合数据库、消息队列等实现复杂逻辑。建议先使用本地内网穿透工具(如ngrok)做测试,再部署到生产环境。

如果你在配置过程中遇到其他问题,欢迎在评论区留言,我们会持续更新教程。

FAQ

Telegram官方客户端选择

常见问题

Telegram为什么要求Webhook必须使用HTTPS?

HTTPS加密可以防止消息内容在传输过程中被窃取和篡改,Telegram官方对安全性要求极高,因此强制要求Webhook使用有效的SSL证书(不支持自签名)。

Webhook和Polling(轮询)该如何选择?

如果服务器有公网IP并能配置SSL证书,推荐使用Webhook,实时性好且节省资源。如果只是开发测试或无法提供HTTPS环境,可以使用Polling,通过getUpdates每秒拉取一次消息。

设置Webhook后还能用getUpdates获取消息吗?

不能。Telegram允许每个机器人同时只启用一种模式,Webhook激活时使用getUpdates会报错。必须删除Webhook后才能使用轮询。

如何判断Webhook是否工作正常?

调用getWebhookInfo接口,查看last_error_message字段是否为空,pending_update_count是否持续增长但处理完毕。若一切正常,该字段通常无内容。