You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Telegram Webhook重复请求问题求助(PHP应用场景)

解决Telegram Webhook重复发送POST请求的问题

我看到你遇到了Telegram Webhook重复发送请求的问题——虽然你的PHP应用返回了200 OK,用户也能收到Bot的回复,但Telegram还是不断重试请求。从你提供的getWebhookInfo响应来看,核心问题是Unsupported Media Type: unsupported content-encoding这个错误,这才是Telegram判定请求未被正确处理、进而重复发送的根本原因,而不是单纯的200响应。

下面是针对性的解决方案:

1. 确认PHP启用zlib扩展

Telegram会用gzip压缩Webhook请求的JSON数据,你的PHP应用需要zlib扩展来解压这些请求:

  • 检查扩展状态:
    • 创建phpinfo.php文件并访问,查看zlib相关配置是否存在;
    • 或在命令行执行:php -m | grep zlib,输出zlib则说明已启用。
  • 未启用的话:
    • 打开php.ini,找到extension=zlib.so(Linux)或extension=php_zlib.dll(Windows),去掉前面的注释符号;
    • 确保zlib.output_compression = On(可选,优化响应压缩);
    • 重启Web服务器(Apache/Nginx)和PHP-FPM(若使用)。

2. 在应用中手动处理gzip压缩的请求体

即使启用了zlib扩展,PHP默认不会自动处理gzip压缩的POST数据,需要手动解压。在Webhook处理脚本最开头添加以下代码:

// 检查请求是否使用gzip压缩
if (isset($_SERVER['HTTP_CONTENT_ENCODING']) && strpos($_SERVER['HTTP_CONTENT_ENCODING'], 'gzip') !== false) {
    // 读取原始压缩请求体
    $rawInput = file_get_contents('php://input');
    // 解压内容
    $decodedInput = gzdecode($rawInput);
    // 将解压后的JSON解析到$_POST(适配依赖$_POST的逻辑)
    if ($decodedInput) {
        $_POST = json_decode($decodedInput, true);
    }
}

如果你使用Telegram Bot SDK,需要修改SDK内部的请求处理逻辑,确保它能读取并解压php://input的内容,而非直接依赖$_POST

3. 确保响应符合Telegram的要求

除了200状态码,响应格式也会影响Telegram的判断:

  • 响应的Content-Type建议设为application/jsontext/plain
  • 处理成功时返回空响应或简单的{"ok": true}即可,无需额外内容;
  • 示例响应代码:
http_response_code(200);
header('Content-Type: application/json');
echo json_encode(['ok' => true]); // 或直接echo '';
exit; // 确保脚本立即终止,避免输出多余内容

4. 重置Webhook并验证修复效果

完成修改后,需要重置Webhook清除错误状态:

  • 调用Telegram Bot API的deleteWebhook方法(可用curl或SDK实现);
  • 重新设置Webhook,确保URL正确;
  • 再次调用getWebhookInfo,检查:
    • last_error_message是否消失;
    • pending_update_count是否逐渐减少(说明Telegram不再重复发送请求)。

额外排查点

  • 若使用反向代理(如Nginx),确保代理未修改Content-Encoding头,可在location配置中添加:
    proxy_set_header Accept-Encoding "";
    proxy_pass_request_headers on;
    
  • 查看服务器错误日志,确认是否有解压失败的相关报错;
  • 验证服务器响应时间不超过5秒(Telegram的超时阈值)。

内容的提问来源于stack exchange,提问作者Арсен Гоян

火山引擎 最新活动