I'm trying to set up a telegram bot with a webhook. I can get it to work with getUpdates, but I want it to work with a webhook.
My site (that hosts the bot php script) has the SSL certificate working (I get the green lock in the address bar):
I set up the webhook with
https://api.telegram.org/bot<token>/setwebhook?url=https://www.example.com/bot/bot.php
And I got: {"ok":true,"result":true,"description":"Webhook was set"}
(I don't know if this matters, but I have given rwx rights to both the folder and the script)
The php bot: (https://www.example.com/bot/bot.php)
<?php
$botToken = <token>;
$website = "https://api.telegram.org/bot".$botToken;
#$update = url_get_contents('php://input');
$update = file_get_contents('php://input');
$update = json_decode($update, TRUE);
$chatId = $update["message"]["chat"]["id"];
$message = $update["message"]["text"];
switch($message) {
case "/test":
sendMessage($chatId, "test");
break;
case "/hi":
sendMessage($chatId, "hi there!");
break;
default:
sendMessage($chatId, "default");
}
function sendMessage ($chatId, $message) {
$url = $GLOBALS[website]."/sendMessage?chat_id=".$chatId."&text=".urlencode($message);
url_get_contents($url);
}
function url_get_contents($Url) {
if(!function_exists('curl_init')) {
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
?>
But when I write anything to the bot I receive no answers...
Any ideas why?
Thanks
In your question it's not clear the script location. Seeing your code, it seems that you try to load a request through url_get_contents to retrieve telegram server response. This is the correct method if your bot works without webhook. Otherwise, after setting webhook, you have to process incoming requests.
I.e., if you set webhook to https://example.com/mywebhook.php, in your https://example.com/mywebhook.php script you have to write something like this:
<?php
$request = file_get_contents( 'php://input' );
# ↑↑↑↑
$request = json_decode( $request, TRUE );
if( !$request )
{
// Some Error output (request is not valid JSON)
}
elseif( !isset($request['update_id']) || !isset($request['message']) )
{
// Some Error output (request has not message)
}
else
{
$chatId = $request['message']['chat']['id'];
$message = $request['message']['text'];
switch( $message )
{
// Process your message here
}
}
Related
So I'm trying to create a Facebook Messenger Chatbot, a very simple one. I have it working with a hardcoded response, but I want it to be able to read the senders message and respond in a specific way if it finds that word - like how chatbots should. I' trying to do so by using preg_match() but when I use my current code, the bot doesn't reply at all. Here's my code:
<?php
/**
* Webhook for Facebook Messenger Bot
*/
$access_token = "{mytoken}";
$verify_token = "{mytoken2}";
$hub_verify_token = null;
if (isset($_REQUEST['hub_challenge'])) {
$challenge = $_REQUEST['hub_challenge'];
$hub_verify_token = $_REQUEST['hub_verify_token'];
}
if ($hub_verify_token == $verify_token) {
echo $challenge;
}
$input = json_decode(file_get_contents('php://input'), true);
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
$message = $input['entry'][0]['messaging'][0]['message']['text'];
// perform a case-Insensitive search for the word "time"
if (preg_match('[hi|hello|sup]', $message)) {
$answer = "Hiya!";
}
else {
$answer = "IDK.";
}
// send the response back to sender
// 'text': 'Hiya!'
$jsonData = "{
'recipient': {
'id': $sender
},
'message': {
'text': $answer
}
}";
// initiate cURL.
$ch = curl_init("https://graph.facebook.com/v2.6/me/messages?access_token=$access_token");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
if (!empty($input['entry'][0]['messaging'][0]['message'])) {
curl_exec($ch);
}
Do you know whether you actually receive messages from the Messenger Platform? Your webhook verification ends in an echo, where in fact you need to respond to the platform with a status code 200. You can also check your Facebook Apps dashboard to figure out whether your webhook is verified and being sent messages.
Documentation: https://developers.facebook.com/docs/messenger-platform/getting-started/webhook-setup
Once you know that your webhook is verified and you are receiving messages, start with a fixed reply and then work towards dynamic responses. As #Toto suggested, adding logging will be very helpful to debug your code.
I would like to write messenger bot based on this script:
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
// Set this Verify Token Value on your Facebook App
if ($verify_token === 'testtoken') {
echo $challenge;
}
$input = json_decode(file_get_contents('php://input'), true);
// Get the Senders Graph ID
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
// Get the returned message
$message = $input['entry'][0]['messaging'][0]['message']['text'];
//API Url and Access Token, generate this token value on your Facebook App Page
$url = 'https://graph.facebook.com/v2.6/me/messages?access_token=<ACCESS-TOKEN-VALUE>';
//Initiate cURL.
$ch = curl_init($url);
//The JSON data.
$jsonData = '{
"recipient":{
"id":"' . $sender . '"
},
"message":{
"text":"The message you want to return"
}
}';
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
//Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//Execute the request but first check if the message is not empty.
if(!empty($input['entry'][0]['messaging'][0]['message'])){
$result = curl_exec($ch);
}
?>
All works correctly but i receive two responses to variable $message, for example:
Send "Hello";
$message = "Hello";
Receive message: "Hi";
$message = "Hi";
I would like to skip 3 and 4 points and receive only "Hello" message because i have to check if $message is my question or answer. Is it possible?
Greetings
You should skip any read and delivery messages, like this:
if (!empty($input['entry'][0]['messaging'])) {
foreach ($input['entry'][0]['messaging'] as $message) {
// Skipping delivery messages
if (!empty($message['delivery'])) {
continue;
}
// Skipping read messages
if (!empty($message['read'])) {
continue;
}
}
}
Or, you can deselect message_reads & message_deliveries checkboxes in Page Subscription section of your Facebook Page Settings/Webhooks.
I'm trying to set up a fb messenger chatbot but don't seem to be able to get the webhook callback url verified. Every time I try to verify it I get this error message - The URL couldn't be validated. Response does not match challenge, expected value = '1596214014', received=''
Here's the screenshot:
Screenshot
Here's the php I'm using -
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
I've also tried
echo $_GET['hub_challenge'];
and just
echo file_get_contents('php://input');
All of these result in the same error message as above. Basically, as far as I can tell facebook isn't sending a GET request to my server or if it is it doesn't include any data. Can anyone tell if I am doing something wrong or if there is a setting I need to change to ensure facebook is sending the data correctly?
Edit - When checking the access logs this is what I find, which looks like facebook isn't sending any data in the get request.
2a03:2880:1010:dffb:face:b00c:0:8000 - - [19/Apr/2016:20:50:06 +0000] "GET /wp-content/plugins/applications/fbmessenger.php HTTP/1.0" 200 - "-" "facebookplatform/1.0 (+http://developers.facebook.com)
Thanks
just try my code and it's gonna work.
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'Your's app token') {
echo $challenge;
}
//Token of app
$row = "Token";
$input = json_decode(file_get_contents('php://input'), true);
//Receive user
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
//User's message
$message = $input['entry'][0]['messaging'][0]['message']['text'];
//Where the bot will send message
$url = 'https://graph.facebook.com/v2.6/me/messages?access_token='.$row;
$ch = curl_init($url);
//Answer to the message adds 1
if($message)
{
$jsonData = '{
"recipient":{
"id":"'.$sender.'"
},
"message":{
"text":"'.$message. ' 1' .'"
}
}';
};
$json_enc = $jsonData;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_enc);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
if(!empty($input['entry'][0]['messaging'][0]['message'])){
$result = curl_exec($ch);
}
you have to return Challenges so Facebook can verify its correct Url and Token Match
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
Facebook Docs Link ( In Node.js ) You can see challenge return after verifying the token
https://developers.facebook.com/docs/messenger-platform/getting-started/webhook-setup
Could you try my API? https://github.com/Fritak/messenger-platform
If you set it like in example, it should work:
// This is just an example, this method of getting request is not safe!
$stream = file_get_contents("php://input");
$request = empty($stream)? $_REQUEST : $stream;
$bot = new \fritak\MessengerPlatform(
['accessToken' => 'token_for_app',
'webhookToken' => 'my_secret_token',
'facebookApiUrl' => 'https://graph.facebook.com/v2.6/me/' //2.6 is minimum
], $request);
if($bot->checkSubscribe())
{
print $bot->request->getChallenge();
exit;
}
If not, problem is somewhere between Facebook and script, not in PHP itself. Go check apache settings etc.
Well issue might be on facebook side, they had some issues over past few days...
Have only this code in your php file: (fbmessenger.php)
<?php
// header('HTTP/1.1 200 OK');
/* GET ALL VARIABLES GET & POST */
foreach ($_REQUEST AS $key => $value){
$message .= "$key => $value ($_SERVER[REQUEST_METHOD])\n";
}
$input = file_get_contents("php://input");
$array = print_r(json_decode($input, true), true);
file_put_contents('fbmessenger.txt', $message.$array."\nREQUEST_METHOD: $_SERVER[REQUEST_METHOD]\n----- Request Date: ".date("d.m.Y H:i:s")." IP: $_SERVER[REMOTE_ADDR] -----\n\n", FILE_APPEND);
echo $_REQUEST['hub_challenge'];
You will have requests saved in a file called "fbmessenger.txt" in the same directory.
Note that for some strange reason you may need to submit few times to
get it approved & saved! (I had to hit "save" 8-9 times before fb
approved link)
Make sure you use https (SSL) connection and once your connection is done, verify your token with "hub_verify_token" to make sure request is coming from fb.
I am trying to create a php gotomeating api implementation. I successfully got the access_token but for any other requests I get error responses. This is my code:
<?php
session_start();
$key = '#';
$secret = '#';
$domain = $_SERVER['HTTP_HOST'];
$base = "/oauth/index.php";
$base_url = urlencode("http://$domain$base");
$OAuth_url = "https://api.citrixonline.com/oauth/authorize?client_id=$key&redirect_uri=$base_url";
$OAuth_exchange_keys_url = "http://api.citrixonline.com/oauth/access_token?grant_type=authorization_code&code={responseKey}&client_id=$key";
if($_SESSION['access_token']) CreateForm();else
if($_GET['send']) OAuth_Authentication($OAuth_url);
elseif($_GET['code']) OAuth_Exchanging_Response_Key($_GET['code'],$OAuth_exchange_keys_url);
function OAuth_Authentication ($url){
$_SESSION['access_token'] = false;
header("Location: $url");
}
function CreateForm(){
$data = getURL('https://api.citrixonline.com/G2M/rest/meetings?oauth_token='.$_SESSION['access_token'],false);
}
function OAuth_Exchanging_Response_Key($code,$url){
if($_SESSION['access_token']){
CreateForm();
return true;
}
$data = getURL(str_replace('{responseKey}',$code,$url));
if(IsJsonString($data)){
$data = json_decode($data);
$_SESSION['access_token'] = $data->access_token;
CreateForm();
}else{
echo 'error';
}
}
/*
* Helper functions
*/
/*
* checks if a string is json
*/
function IsJsonString($str){
try{
$jObject = json_decode($str);
}catch(Exception $e){
return false;
}
return (is_object($jObject)) ? true : false;
}
/*
* CURL function to get url
*/
function getURL($url,$auth_token = false,$data=false){
// Initialize session and set URL.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Set so curl_exec returns the result instead of outputting it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if($auth_token){
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: OAuth oauth_token='.$auth_token));
}
if($data){
curl_setopt($ch, CURLOPT_POST,true);
$d = json_encode('{ "subject":"test", "starttime":"2011-12-01T09:00:00Z", "endtime":"2011-12-01T10:00:00Z", "passwordrequired":false, "conferencecallinfo":"test", "timezonekey":"", "meetingtype":"Scheduled" }');
echo implode('&', array_map('urlify',array_keys($data),$data));
echo ';';
curl_setopt($ch, CURLOPT_POSTFIELDS,
implode('&', array_map('urlify',array_keys($data),$data))
);
}
// Get the response and close the channel.
$response = curl_exec($ch);
/*
* if redirect, redirect
*/
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($code == 301 || $code == 302) {
preg_match('/<a href="(.*?)">/', $response, $matches);
$newurl = str_replace('&','&',trim(array_pop($matches)));
$response = getURL($newurl);
} else {
$code = 0;
}
curl_close($ch);
return $response;
}
function urlify($key, $val) {
return urlencode($key).'='.urlencode($val);
}
to start the connect process you need to make a request to the php file fith send=1. I tryed diffrent atempts to get the list of meetings but could not get a good response.
Did anybody had prev problems with this or know of a solution for this?
Edit:
This is not a curl error, the server responds with error messages, in the forums from citrix they say it should work, no further details on why it dosen't work, if I have a problem with the way I implemented the oauth or the request code. The most comon error I get is: "error code:31305" that is not documented on the forum.
[I also posted this on the Citrix Developer Forums, but for completeness will mention it here as well.]
We are still finalizing the documentation for these interfaces and some parameters which are written as optional are actually required.
Compared to your example above, changes needed are:
set timezonekey to 67 (Pacific time)
set passwordrequired to false
set conferencecallinfo to Hybrid (meaning: both PSTN and VOIP will be provided)
Taking those changes into account, your sample data would look more like the following:
{"subject":"test meeting", "starttime":"2012-02-01T08:00:00",
"endtime":"2012-02-01T09:00:00", "timezonekey":"67",
"meetingtype":"Scheduled", "passwordrequired":"false",
"conferencecallinfo":"Hybrid"}
You can also check out a working PHP sample app I created: http://pastebin.com/zE77qzAz
I need to create a function that returns if a URL is reachable or valid.
I am currently using something like the following to determine a valid url:
static public function urlExists($url)
{
$fp = #fopen($url, 'r');
if($fp)
{
return true;
}
return false;
}
It seems like there would be something faster, maybe something that just fetched the page header or something.
You can use curl as follows:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true); // set to HEAD request
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // don't output the response
curl_exec($ch);
$valid = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200;
curl_close($ch);
You could check http status code.
Here is a code you could use to check that an url returns 2xx or 3xx http code to ensure the url works.
<?php
$url = "http://stackoverflow.com/questions/1122845";
function urlOK($url)
{
$url_data = parse_url ($url);
if (!$url_data) return FALSE;
$errno="";
$errstr="";
$fp=0;
$fp=fsockopen($url_data['host'],80,$errno,$errstr,30);
if($fp===0) return FALSE;
$path ='';
if (isset( $url_data['path'])) $path .= $url_data['path'];
if (isset( $url_data['query'])) $path .= '?' .$url_data['query'];
$out="GET /$path HTTP/1.1\r\n";
$out.="Host: {$url_data['host']}\r\n";
$out.="Connection: Close\r\n\r\n";
fwrite($fp,$out);
$content=fgets($fp);
$code=trim(substr($content,9,4)); //get http code
fclose($fp);
// if http code is 2xx or 3xx url should work
return ($code[0] == 2 || $code[0] == 3) ? TRUE : FALSE;
}
echo $url;
if (urlOK($url)) echo " is a working URL";
else echo " is a bad URL";
?>
Hope this helps!
You'll likely be limited to sending some kind of HTTP request. Then you can check HTTP status codes.
Be sure to send only a "HEAD" request, which doesn't pull back all the content. That ought to be sufficient and lightweight enough.