FB messenger Bot not getting postback payloads - php

I am developing a facebook chatbot. I am facing a issue which I cannot solve. I am developing this in laravel. Here I cannot get the postback payload. here is my code
public function index(Request $request) {
if ($request->hub_verify_token === $this->verifyToken) {
echo $request->hub_challenge;
exit;
}
$input = json_decode(file_get_contents("php://input"), true);
$senderId = $input['entry'][0]['messaging'][0]['sender']['id'];
$messageText = $input['entry'][0]['messaging'][0]['message']['text'];
$pageId = $input['entry'][0]['id'];
$accessToken = "access_token_that_got_from_fb";
//set Message
if($messageText != "") {
$answer = "Howdy! User";
}
if($messageText == "hello") {
$answer = 'Testing hello from bot';
}
foreach ($input['entry'][0]['messaging'] as $message) {
// When bot receive message from user
if (!empty($message['postback'])) {
$answer = 'got it tada';
}
}
//send message to facebook bot
$response = [
'recipient' => [ 'id' => $senderId ],
'message' => [ 'text' => $answer ] //json_encode($request->getContent())
];
$ch = curl_init('https://graph.facebook.com/v2.11/me/messages?access_token='.$accessToken);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($response));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$result = curl_exec($ch);
curl_close($ch);
}
and my route is
Route::any('chatbot', 'ChatbotController#index');
here the message is working . but the postback payload request is not going to server. on the other hand using the same code in normal php file I am able to get postback paylod.
$hubVerifyToken = 'chatbot';
$accessToken = "access_token";
// check token at setup
if ($_REQUEST['hub_verify_token'] === $hubVerifyToken) {
echo $_REQUEST['hub_challenge'];
exit;
}
// handle bot's anwser
$input = json_decode(file_get_contents('php://input'), true);
$senderId = $input['entry'][0]['messaging'][0]['sender']['id'];
$messageText = $input['entry'][0]['messaging'][0]['message']['text'];
$postback = isset($input['entry'][0]['messaging'][0]['postback']['payload']) ? $input['entry'][0]['messaging'][0]['postback']['payload'] : '' ;
//set Message
if($messageText == "hi") {
$answer = "Hello";
}
if($messageText == "hello") {
$answer = "Hello there, welcome to Chatleads";
}
if($postback) {
$answer = "postback TADA";
}
//send message to facebook bot
$response = [
'recipient' => [ 'id' => $senderId ],
'message' => [ 'text' => $answer ]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com/v2.11/me/messages?access_token=$accessToken");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($response));
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
How to solve this issue? can anyone show me a path?

Solved it by checking at laravel.log file.
$this->messageText = isset($this->input['entry'][0]['messaging'][0]['message']['text']) ? $this->input['entry'][0]['messaging'][0]['message']['text'] : '' ;
messageText should be like this. that's why its causing an error.

Related

How to Send automated SMS using API?

I have this condition to scheduled my sms. (ERROR) but the sms I'm using is POST method I need to be automated. And send sms to the number of the current id. I don't know how to get the number of the current id and send the message. Here is my code:
$duedate = "";
$date_now = date("Y-m-d");
date_default_timezone_set('Asia/Manila');
$date_now = strtotime($date_now);
$duedate = strtotime($duedate);
if ($duedate <= $date_now) {
function itexmo($number, $message, $apicode) {
$url = 'https://www.itexmo.com/php_api/api.php';
$itexmo = array('1' => $number, '2' => $message, '3' => $apicode);
$param = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($itexmo),
),
);
$context = stream_context_create($param);
return file_get_contents($url, false, $context);
}
if ($_POST) {
$number = $number;
$name = $name;
$api = "API";
$text = $name." : ".$number;
if (!empty($_POST['name']) && ($_POST['number']) && ($_POST['msg'])) {
$result = itexmo($number, $text, $api);
if ($result == "") {
echo "iTexMo: No response from server!!!
Please check the METHOD used (CURL or CURL-LESS). If you are using CURL then try CURL-LESS and vice versa.
Please CONTACT US for help. ";
} elseif ($result == 0) {
echo "Message Sent!";
} else {
echo "Error Num ". $result . " was encountered!";
}
}
}
}
It is better to use PHP cURL than stream_context_create and file_get_contents.
Take a look at below code, it should help you.
function itexmo($number,$message,$apicode)
{
$url = 'https://www.itexmo.com/php_api/api.php';
$postValues = http_build_query(['1' => $number, '2' => $message, '3' => $apicode])
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postValues);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"cache-control: no-cache",
"content-type: application/x-www-form-urlencoded"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close ($ch);
return $response;
}
You can learn more PHP cURL.

pushcrew - send notification with PHP curl

This is the code:
$title = 'Du hast neue Nachricht';
$message = 'Besuch meine Website';
$url = 'https://www.bla.com';
$subscriberId = 'xxx51a002dec08a1690fcbe6e';
$apiToken = 'xxxe0b282d9c886456de0e294ad';
$curlUrl = 'https://pushcrew.com/api/v1/send/individual/';
//set POST variables
$fields = array(
'title' => $title,
'message' => $message,
'url' => $url,
'subscriber_id' => $subscriberId
);
$httpHeadersArray = Array();
$httpHeadersArray[] = 'Authorization: key='.$apiToken;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $curlUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_HTTPSHEADER, $httpHeadersArray);
//execute post
$result = curl_exec($ch);
$resultArray = json_decode($result, true);
if($resultArray['status'] == 'success') {
echo $resultArray['request_id']; //ID of Notification Request
}
else if($resultArray['status'] == 'failure')
{
echo 'fail';
}
else
{
echo 'dono';
}
echo '<pre>';
var_dump($result);
echo '</pre>';
And I get:
dono
string(36) "{"message":"You are not authorized"}"
And nothing in the console and no other errors. The apitoken is 100% correct. What could be the trouble here? Do I have to wait till pushcrew decide to allow my website or something?
Ignore this: I must add some more text to ask this question..
There is typo here:
curl_setopt($ch, CURLOPT_HTTPSHEADER, $httpHeadersArray);
Correct is with
CURLOPT_HTTPHEADER
(without the S)

Laravel FCM push notification with Firebase not working on iOS, but fine with Android

I have tried Firebase notification with Laravel to send notification to IOS and Android devices.
But IOS device not received the notifications but Android devices working good.
So what is the issue in my script?
I have tried following,
$firebase = new \Firebase();
$push = new \Push();
// optional payload
$payload = array();
$payload['team'] = 'India';
$payload['score'] = '5.6';
// notification title
$title = Input::get('title');
// notification message
$message = Input::get('message');
// push type - single user / topic
$push_type = Input::get('push_type');
// whether to include to image or not
$include_image = Input::get('include_image') ? TRUE : FALSE;
$include_image = TRUE;
$push->setTitle($title);
$push->setMessage($message);
if ($include_image) {
$push->setImage('http://api.androidhive.info/images/minion.jpg');
} else {
$push->setImage('');
}
$push->setIsBackground(FALSE);
$push->setPayload($payload);
$json = '';
$response = '';
if ($push_type == 'topic') {
$json = $push->getPush();
$response = $firebase->sendToTopic('global', $json);
} else if ($push_type == 'individual') {
$json = $push->getPush();
$regId = Input::get('regId');
$response = $firebase->send($regId, $json);
}
I have refer this question but there is no answer provided.
you need a 'notification' json block for iOS to respond
$url = "https://fcm.googleapis.com/fcm/send";
$token = "";
$serverKey = '';
$title = "Title";
$body = "Body of the message";
$notification = array('title' =>$title , 'text' => $body, 'sound' => 'default', 'badge' => '1');
$arrayToSend = array('to' => $token, 'notification' => $notification,'priority'=>'high');
$json = json_encode($arrayToSend);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: key='. $serverKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,
"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
//Send the request
$response = curl_exec($ch);
//Close request
if ($response === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);

send gcm message in groups of 1000 users to all 10000 users

i am using following code to send gcm message using php and mysqldb i have successfully send the gcm message and received it on the device however the android guidelines state that gcm message should be send in batch of 1000 each http://developer.android.com/training/cloudsync/gcm.html#multicast
now my question is how can we send gcm messages in lots of 1000 to a database of say 10,000 registered users.
<?php
require 'connect.php';
function sendPushNotification($registration_ids, $message) {
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registration_ids,
'data' => $message,
);
define('GOOGLE_API_KEY', 'keys_value');
$headers = array(
'Authorization:key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
echo json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if($result === false)
die('Curl failed ' . curl_error());
curl_close($ch);
return $result;
}
$pushStatus = '';
if(!empty($_GET['push'])) {
$query = "SELECT gcm_regId FROM gcm_users";
if($query_run = mysql_query($query)) {
$gcmRegIds = array();
while($query_row = mysql_fetch_assoc($query_run)) {
array_push($gcmRegIds, $query_row['gcm_regId']);
}
}
$pushMessage = $_POST['message'];
if(isset($gcmRegIds) && isset($pushMessage)) {
$message = array('price' => $pushMessage);
$pushStatus = sendPushNotification($gcmRegIds, $message);
}
}
?>
<html>
<head>
<title>Google Cloud Messaging (GCM) Server in PHP</title>
</head>
<body>
<h1>Google Cloud Messaging (GCM) Server in PHP</h1>
<form method = 'POST' action = 'send_all.php/?push=1'>
<div>
<textarea rows = 2 name = "message" cols = 23 placeholder = 'Messages to Transmit via GCM'></textarea>
</div>
<div>
<input type = 'submit' value = 'Send Push Notification via GCM'>
</div>
<p><h3><?php echo $pushStatus ?></h3></p>
</form>
</body>
</html>
Make $gcmRegIds to be a 2D array and then foreach it to push msg:
if(!empty($_GET['push'])) {
$query = "SELECT gcm_regId FROM gcm_users";
if($query_run = mysql_query($query)) {
$gcmRegIds = array();
$i = 0;
while($query_row = mysql_fetch_assoc($query_run)) {
$i++;
$gcmRegIds[floor($i/1000)][] = $query_row['gcm_regId'];
}
}
$pushMessage = $_POST['message'];
if(isset($gcmRegIds) && isset($pushMessage)) {
$message = array('price' => $pushMessage);
$pushStatus = array();
foreach($gcmRegIds as $val) $pushStatus[] = sendPushNotification($val, $message);
}
}
Here is what i did for my scenario to resolve for FCM .You can also ignore some parts of the code
<?php
$saved_tokens=array(); // could be more than 1000 token the maximum size as per google FCM requirement
//$count=1;
$ID_SETS = array_chunk($saved_tokens, 1000); // make a group of 1000 items in each set
foreach ($ID_SETS as $value_ids) {
// echo "Chunk ".$count."<br>";
sendFCM_Notification("what_ever_parameter_data",$value_ids);
foreach ($value_ids as $value_i ) { // you can remove this part its not neccessary
//echo " ---- contents of Chunk ".$count ."with Value".$value_i."<br>";
}
// $count++;
}
function sendFCM_Notification($what_ever_parameter,$reg_ids_array){
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $reg_ids_array,
'data' => $what_ever_parameter
);
$headers = array(
'Authorization:key = YOUR_KEY ',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>

Send multiple messages with GCM

I've been dealing with this issue since 2 days. What I want to do is, I've to send multiple messages to registered GCM device. Till now I can send single message to device. Below is the code to send message.
send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("price" => $message);
$result = $gcm->send_notification($registatoin_ids, $message);
echo $registatoin_ids; echo $message;
echo $result;
}
GCM.php
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
//Sending Push Notification
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
Here message is being received on receiver side..
// code for this is in GCM.php
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
);
But I want to send multiple messages in single notification. for that what I did...
send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"]) && isset($_REQUEST["data"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
$data = $_REQUEST["data"]; //added third parameter
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("price" => $message);
$data = array("extra" => $data);
$result = $gcm->send_notification($registatoin_ids, $message, $data);
echo $registatoin_ids; echo $message; echo $data;
echo $result;
}
GCM.php
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message, $data) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
'data' => $data,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
And in android I wrote the function to receive message like this...
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getStringExtra("price");
String newmessage = intent.getStringExtra("extra");
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}
But I'm getting null result for "price" and getting result for "extra".
How can I receive multiple message string in single notification?
In send_message.php
Put both messages in the same object. I don't know why you call it price, but try like this:
$message = array('message' => $message,
'extra' => $data
);
In GCM.php
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
In your Android Service
protected void onMessage(Context context, Intent intent) {
//log the message in JSON format
Log.i(TAG, "Received message >> " + intent.getExtras().toString());
//Retrieve message and extra
String message = intent.getExtras().getString("message");
String newmessage = intent.getExtras().getString("extra");
//Now display the message
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}
All the payload parameters you pass in your JSON should be within the data element.
Your JSON should look like this :
{
"registration_ids":["xxx", "yyy"],
"data": {
"price": "price value",
"extra": "extra value"
}
}
And not like this :
{
"registration_ids":["xxx", "yyy"],
"message": {
"price": "price value"
},
"data": {
"extra": "extra value"
}
}
you can write a JSON response that contain a multiple messages
and the you get the JSON in android , parse it and get your multiple Messages .
send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"]) && isset($_REQUEST["extra"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
$extra= $_REQUEST["extra"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("message" => $message, "extra" => $extra);
$result = $gcm->send_notification($registatoin_ids, $message);
}
GCM.php
<?php
class GCM {
function __construct() {
}
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo 'result';
echo json_encode($fields);
echo $result;
}
}
Android side
/**
* Method called on Receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("extra");
String newmessage = intent.getExtras().getString("message");
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}

Categories