web-dev-qa-db-ja.com

Telegram Bot APIへのwebhookで問題が発生しました

Webhookが機能しないのはなぜですか? TelegramボットAPIからデータを取得しません。ここに私の問題の詳細な説明があります:

StartSSLからSSL証明書を取得しました、私のウェブサイトでは正常に動作します( GeoCerts SSLチェッカー による)が、それでもTelegram Bot APIへのWebhookのように見える動作しません(webhookが設定されていると言っても、データを取得しません)。

私はこのフォームで私のウェブサイトのスクリプトにウェブフックを作成しています:

https://api.telegram.org/bot<token>/setWebhook?url=https://mywebsite.com/path/to/giveawaysbot.php

私は応答でこのテキストを受け取ります:

{"ok":true,"result":true,"description":"Webhook was set"}

動作しているはずですが、実際には動作しません。

スクリプトコードを次に示します。

<?php 

ini_set('error_reporting', E_ALL);

$botToken = "<token>";
$website = "https://api.telegram.org/bot".$botToken;

$update = file_get_contents('php://input');
$update = json_decode($update);

print_r($update); // this is made to check if i get any data or not

$chatId = $update["message"]["chat"]["id"];
$message = $update["message"]["text"];


switch ($message) {
    case "/test":
        sendMessage($chatId,"test complete");
        break;
    case "/hi":
        sendMessage($chatId,"hey there");
        break;
    default:
        sendMessage($chatId,"nono i dont understand you");
}


function sendMessage ($chatId, $message) {
    $url = $GLOBALS[website]."/sendMessage?chat_id=".$chatId."&text=".urlencode($message);
    file_get_contents($url);
}

?>

$ updateのデータは実際には受け取りません。そのため、webhookは機能していません。どうして?

21
markelov

私はこの問題を抱えていました。問題はSSL証明書であると人々はいつも言っていたので、私はどこでも調べようとして、私の問題の解決策を見つけることができませんでした。しかし、私は問題を見つけました。それは、カールやこの種のものを巻き込むテレグラムAPI webhookと対話するためのコードに欠けている多くのものでした。電報ボットのドキュメントの例を見て、問題を解決しました。この例を見てください https://core.telegram.org/bots/samples/hellobot

<?php
//telegram example
define('BOT_TOKEN', '12345678:replace-me-with-real-token');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');

function apiRequestWebhook($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  header("Content-Type: application/json");
  echo json_encode($parameters);
  return true;
}

function exec_curl_request($handle) {
  $response = curl_exec($handle);

  if ($response === false) {
    $errno = curl_errno($handle);
    $error = curl_error($handle);
    error_log("Curl returned error $errno: $error\n");
    curl_close($handle);
    return false;
  }

  $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
  curl_close($handle);

  if ($http_code >= 500) {
    // do not wat to DDOS server if something goes wrong
    sleep(10);
    return false;
  } else if ($http_code != 200) {
    $response = json_decode($response, true);
    error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n");
    if ($http_code == 401) {
      throw new Exception('Invalid access token provided');
    }
    return false;
  } else {
    $response = json_decode($response, true);
    if (isset($response['description'])) {
      error_log("Request was successfull: {$response['description']}\n");
    }
    $response = $response['result'];
  }

  return $response;
}

function apiRequest($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  foreach ($parameters as $key => &$val) {
    // encoding to JSON array parameters, for example reply_markup
    if (!is_numeric($val) && !is_string($val)) {
      $val = json_encode($val);
    }
  }
  $url = API_URL.$method.'?'.http_build_query($parameters);

  $handle = curl_init($url);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);

  return exec_curl_request($handle);
}

function apiRequestJson($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  $handle = curl_init(API_URL);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);
  curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
  curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));

  return exec_curl_request($handle);
}

function processMessage($message) {
  // process incoming message
  $message_id = $message['message_id'];
  $chat_id = $message['chat']['id'];
  if (isset($message['text'])) {
    // incoming text message
    $text = $message['text'];

    if (strpos($text, "/start") === 0) {
      apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => 'Hello', 'reply_markup' => array(
        'keyboard' => array(array('Hello', 'Hi')),
        'one_time_keyboard' => true,
        'resize_keyboard' => true)));
    } else if ($text === "Hello" || $text === "Hi") {
      apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Nice to meet you'));
    } else if (strpos($text, "/stop") === 0) {
      // stop now
    } else {
      apiRequestWebhook("sendMessage", array('chat_id' => $chat_id, "reply_to_message_id" => $message_id, "text" => 'Cool'));
    }
  } else {
    apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'I understand only text messages'));
  }
}


define('WEBHOOK_URL', 'https://my-site.example.com/secret-path-for-webhooks/');

if (php_sapi_name() == 'cli') {
  // if run from console, set or delete webhook
  apiRequest('setWebhook', array('url' => isset($argv[1]) && $argv[1] == 'delete' ? '' : WEBHOOK_URL));
  exit;
}


$content = file_get_contents("php://input");
$update = json_decode($content, true);

if (!$update) {
  // receive wrong update, must not happen
  exit;
}

if (isset($update["message"])) {
  processMessage($update["message"]);
}
?>
7
bzim

同様の問題がありました。今解決しました。問題は、おそらく間違った公開証明書にあります。私のプロジェクトで提案する注意事項に従ってください:

https://github.com/solyaris/BOTServer/blob/master/wiki/usage.md#step-4-create-self-signed-certificate

openssl req -newkey rsa:2048 -sha256 -nodes -keyout /your_home/BOTServer/ssl/PRIVATE.key -x509 -days 365 -out /your_home/BOTServer/ssl/PUBLIC.pem -subj "/C=IT/ST=state/L=location/O=description/CN=your_domain.com"

Telegram setWebhooks APIは、自己署名デジタル証明書内のデータをチェックせず、例として有効な/ CNを指定しなくても「ok」を返します。したがって、REALホストのドメイン名に対応する/ CN = your_domainを含むパブリック.pem証明書を生成するよう注意してください!

3
Giorgio Robino

SSL証明書である可能性があります。私は同じ問題を抱えていました:Webhookは確認しましたが、実際にはSSL証明書が壊れました。

このredditスレッドは役に立ちました: https://www.reddit.com/r/Telegram/comments/3b4z1k/bot_api_recieving_nothing_on_a_correctly/

2
robin

私もこの問題を抱えていました。何らかの理由で電報がボットを実行しなかったため、証明書を更新してWebフックを再度設定しようとしましたが、再び機能しませんでしたので、VPSを更新してから更新します証明書とWebフックの再設定。これらの後、再び機能し始めました。

1
Afshin Izadi

このコードを試してください。 Webホストに有効なSSLがあり、setWebhookを適切に実行している場合は、動作するはずです(私にとってはうまくいきます)。 「log.txt」というファイルを作成して、書き込み許可を付与してください。

<?php 
define('BOT_TOKEN', '????');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');

// read incoming info and grab the chatID
$content    = file_get_contents("php://input");
$update     = json_decode($content, true);
$chatID     = $update["message"]["chat"]["id"];
$message    = $update["message"]["text"];

// compose reply
$reply ="";
switch ($message) {
    case "/start":
        $reply =  "Welcome to Siamaks's bot. Type /help to see commands";
        break;
    case "/test":
        $reply =  "test complete";
        break;
    case "/hi":
        $reply =  "hey there";
        break;
    case "/help":
        $reply =  "commands: /start , /test , /hi , /help ";
        break;
    default:
        $reply =  "NoNo, I don't understand you";
}

// send reply
$sendto =API_URL."sendmessage?chat_id=".$chatID."&text=".$reply;
file_get_contents($sendto);

// Create a debug log.txt to check the response/repy from Telegram in JSON format.
// You can disable it by commenting checkJSON.
checkJSON($chatID,$update);
function checkJSON($chatID,$update){

    $myFile = "log.txt";
    $updateArray = print_r($update,TRUE);
    $fh = fopen($myFile, 'a') or die("can't open file");
    fwrite($fh, $chatID ."nn");
    fwrite($fh, $updateArray."nn");
    fclose($fh);
}
0
wmac

これは、Laravel Telegram SDKで作業する人を助けるかもしれません。 Laravel 5.3で自己署名Webhookに問題がありました。 「Webhookが設定されました」というメッセージでTelegramからセットアップとOKの結果を得た後、動作しませんでした。
問題はCSRF検証に関連していました。そこで、私はwebhookのURLをCSRF例外に追加しましたが、今ではすべてが魅力のように機能します。

0
Khalil Laleh

これは、このように証明書を設定していないためです

curl -F "url=https://bot.sapamatech.com/tg" -F "certificate=@/etc/Apache2/ssl/bot.pem" https://api.telegram.org/bot265033849:AAHAs6vKVlY7UyqWFUHoE7Toe2TsGvu0sf4/setWebhook

これを確認してください link Telegram自己署名証明書の設定方法

0
Edwin M