6

我开始编写电报机器人程序,但遇到了问题。当我发送 /start 命令时,它会向我发送一条欢迎消息(正如我编写的那样),但它不会发送一次!它像循环一样不断地发送它!这是来源:

<?php
    define('API_KEY','<token>');
    
    function makereq($method,$datas=[])
    {
        $url = "https://api.telegram.org/bot".API_KEY."/".$method;
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($datas));
        $res = curl_exec($ch);
        if(curl_error($ch)){
            var_dump(curl_error($ch));
        }else{
            return json_decode($res);
        }
    }
    
    $website = "https://api.telegram.org/bot".API_KEY;
    
    $update = json_decode(file_get_contents('php://input'));
    
    $chat_id = $update->message->chat->id;
    $message_id = $update->message->message_id;
    $from_id = $update->message->from->id;
    $name = $update->message->from->first_name;
    $username = $update->message->from->username;
    $textmessage = isset($update->message->text)?$update->message->text:'';
    $reply = $update->message->reply_to_message->forward_from->id;
    $stickerid = $update->message->reply_to_message->sticker->file_id;
    $messageEntity = $update->messageentity->type;
    
    function SendMessage($ChatId, $TextMsg)
    {
     makereq('sendMessage',[
    'chat_id'=>$ChatId,
    'text'=>$TextMsg,
    'parse_mode'=>"MarkDown"]
     );
    }
    if($textmessage == '/start')
    {
      SendMessage($chat_id,'<welcome message>');
    }
    
?>
4

6 回答 6

10

您可能正在使用 webhook。
如果您没有以 http 状态 200 进行响应,则电报机器人 API 认为您的服务器有问题,并每隔几秒钟再次请求,如API 文档中所述

如果请求不成功,我们将在合理的尝试次数后放弃。

所以只需添加header("HTTP/1.1 200 OK");到您的脚本中,瞧!
(如果你的 php 版本大于 5.4 可以使用http_response_code(200);

于 2016-11-15T19:05:33.877 回答
2

如果您polling使用getUpdates,则需要增加偏移量。

偏移量 = 1 + latest_update_id

如果您正在使用WebHooks... https://core.telegram.org/bots/api#update update_id

更新的唯一标识符。更新标识符从某个正数开始,依次递增。如果您使用 Webhooks,此 ID 将变得特别方便,因为它允许您 忽略重复更新或恢复正确的更新顺序,以防它们出现故障。

于 2016-11-14T17:33:23.640 回答
1

我最近遇到了这个问题,并通过向聊天发送一条空白消息来阻止它。您从电报中收到错误消息,但不再发送消息。

于 2020-09-23T15:47:35.050 回答
0

正如Yoily L所说,您必须在电报认为请求失败之前返回 200。

您可以使用fastcgi_finish_request()将响应数据刷新到客户端。 http://php.net/manual/en/function.fastcgi-finish-request.php

http_response_code(200);
fastcgi_finish_request();

// continue execution, send messages and whatever

另外,请注意tuxrampage在文档中的评论:

之后脚本仍然会占用一个 FPM 进程 fastcgi_finish_request()。因此,在长时间运行的任务中过度使用它可能会占用所有 FPM 线程,最高可达pm.max_children. 这将导致网络服务器上的网关错误。

另一个重要的事情是会话处理。只要会话处于活动状态,它们就会被锁定(请参阅文档 session_write_close())。这意味着后续请求将被阻塞,直到会话关闭。

因此,您应该session_write_close()尽快(甚至在之前fastcgi_finish_request())调用以允许后续请求和良好的用户体验。

这也适用于所有其他锁定技术,例如群锁或数据库锁。只要锁处于活动状态,后续请求就可能阻塞。

你可能想检查一下

if (is_callable('fastcgi_finish_request')) {
    ...
}

相关问题中的更多信息:发送 http 响应后继续处理 php

于 2017-11-17T14:48:23.580 回答
0

当我的 Telegram-bot 继续发送消息时,我在数据库中创建了一个记录帖子表。当我在 Telegram-bot 中发送帖子时,用 PHP 算法编写的会检查数据库中是否已经存在新帖子: * 如果存在,我们停止发送帖子的过程;* 如果没有,我们会继续在 Telegram 中发送。所描述的方法允许停止一次又一次发送帖子的循环。

于 2020-02-14T09:27:21.057 回答
0

Telegram 机器人由于 hooks 的结构以及以指定时间格式发送和接收消息,对时间非常敏感。我也遇到了同样的问题,发现使用这个date_default_timezone_set函数删除这个函数后问题就解决了。如果您在代码中更改了时间模板,请将其删除。

于 2020-05-11T07:02:45.163 回答