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 で応答しない場合、Telegram ボット API はサーバーに問題があると判断し、API ドキュメントに記載されているように数秒ごとに再度要求します。

要求が失敗した場合、妥当な回数の試行を行った後、要求を断念します。

header("HTTP/1.1 200 OK");スクリプトに追加するだけで、ほら!
(php のバージョンが 5.4 以上の場合は、 を使用できますhttp_response_code(200);)

于 2016-11-15T19:05:33.877 に答える
2

を使用している場合はpollinggetUpdatesオフセットをインクリメントする必要があります。

オフセット = 1 + latest_update_id

使用している場合WebHooks... https://core.telegram.org/bots/api#update update_id

更新の一意の識別子。更新識別子は、特定の正の数から始まり、順次増加します。この ID は、Webhook を使用している場合に特に便利です。これにより、 繰り返される更新を無視したり、順序が乱れた場合に正しい更新シーケンスを復元したりできるためです。

于 2016-11-14T17:33:23.640 に答える
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. これにより、Web サーバーでゲートウェイ エラーが発生します。

もう 1 つの重要なことは、セッションの処理です。セッションは、アクティブである限りロックされます ( のドキュメントを参照してください session_write_close())。これは、セッションが閉じられるまで後続のリクエストがブロックされることを意味します。

したがって、後続のリクエストと優れたユーザー エクスペリエンスを可能にするためsession_write_close()に、できるだけ早く ( の前でも) を呼び出す必要があります。fastcgi_finish_request()

これは、たとえば群れロックやデータベース ロックなど、他のすべてのロック手法にも当てはまります。ロックがアクティブである限り、後続のリクエストはブロックされる可能性があります。

あなたはおそらくチェックしたいでしょう

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

関連する質問の詳細: http 応答を送信した後、php の処理を​​続行する

于 2017-11-17T14:48:23.580 に答える