You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram PHP机器人群发异常:仅发部分用户且重复发送

问题分析

你的代码存在两个核心问题导致群发异常:

  1. 错误的HTTP响应头:添加的Content-Disposition: attachment这类文件下载头,会让Telegram的Webhook机制无法识别正常响应,进而重复发送触发请求,导致机器人持续给第一个用户重复发消息。
  2. 用户ID读取不规范:fgets()会把文件内的换行符(\n或\r\n)一并读入$send_user,直接传给sendMessage会导致无效用户ID,中断循环;同时while (!feof($handle))的写法存在逻辑漏洞,当fgets()读取到文件最后一行时,可能提前进入循环但已无有效内容。
修复后的代码
if ($user_id == $user_id1) {
    // 先返回Telegram要求的200响应,避免重复触发Webhook
    header("HTTP/1.1 200 OK");
    
    $file = 'user.txt';
    // 读取所有用户ID,自动忽略换行符和空行
    $userIds = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    
    foreach ($userIds as $send_user) {
        // 过滤空ID
        if (trim($send_user) === '') {
            continue;
        }
        // 发送消息,添加延迟避免触发Telegram频率限制
        sendMessage($message['text'], $send_user);
        sleep(1);
    }
    
    exit;
}
关键优化点
  • 优先返回200响应:Telegram的Webhook要求5秒内返回200 OK,超时会重复触发请求。如果用户量较大,建议把群发逻辑放到后台任务(比如用exec()启动独立脚本、或借助消息队列),主脚本先快速返回200,彻底避免重复触发问题。
  • 规范读取用户ID:用file()函数配合FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES参数,直接获取干净的用户ID数组,自动跳过空行和换行符,比fgets()的循环写法更可靠。
  • 添加频率控制:sleep(1)保证每秒发送1条消息,符合Telegram API的频率限制(普通机器人限制30条/秒,保守设置能避免被限制)。
  • 移除无关响应头:删掉Content-Type: text/plain和Content-Disposition: attachment,这些是文件下载专用头,和Webhook响应完全无关。
额外建议

如果用户量较多,同步群发容易超时,推荐异步处理方案:

  1. 管理员发送群发指令后,主脚本立即返回200 OK。
  2. 将群发任务(消息内容、用户ID列表)写入数据库或临时文件。
  3. 用定时脚本(如Cron)定期读取待发送任务,批量执行发送逻辑。

内容的提问来源于stack exchange,提问作者hwbsv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:16:09