webhook error when trying to do ajax - php

I modified it all now I have this file that makes my api work.
auth.php:
<?php
include 'Unirest.php';
function login()
{
$headers = array('Accept' => 'application/json');
$data = array(
"grant_type" => "password",
"client_id" => "myclientid",
"client_secret" => "myclientsecret",
"username" => "username",
"password" => "password"
);
$response = Unirest\Request::post('http://i-scent.fr/api/oauth_token', $headers, $data);
// $response->code;
// $response->headers;
return $response->body->access_token;
}
function device_info($device_id,$token){
$header = array('Accept' => 'application/json',
'Authorization' => 'Bearer '.$token );
$response = Unirest\Request::get('http://i-scent.fr/api/devices/'.$device_id,$header);
echo $response->body->name;
echo "</br>";
}
function diffuse($device_id,$token,$duration,$intensity){
$header = array('Accept' => 'application/json', 'Authorization' => 'Bearer '.$token );
$data = array('time' => 1, 'percent' => 50);
$body = Unirest\Request\Body::form($data);
$response = Unirest\Request::put('http://i-scent.fr/app_dev.php/api/device/'.$device_id.'/actions/diffusion',$header,$body);
echo $response->code;
echo "</br>";
}
When I use all the functions in a simple script it works perfectly on my website. But when I put it like this in my webhook, I have error 500 internal server error. I have all the unirest libraries.
<?php
include "auth.php";
function processMessage($update) {
if($update["result"]["action"] == "sayHello"){
$token = login();
$name = device_info("1966",$token);
diffuse("1966",$token,"0.5","50");
sendMessage(array(
"source" => $update["result"]["source"],
"speech" => "bonjour webhook",
"displayText" => "bonjour webhook",
"contextOut" => array()
));
}
}
function sendMessage($parameters) {
echo json_encode($parameters);
}
$update_response = file_get_contents("php://input");
$update = json_decode($update_response, true);
if (isset($update["result"]["action"])) {
processMessage($update);
}
Error 500 is supposed to mean that the webhokk's script crashed somewhere but I don't know where and why.

Update 2
Based on your most recent code, you're including "auth.php", which works in the original environment (which is being called as part of a web page, it sounds like).
Your code has two functions, device_info() and diffuse(), which output their results instead of returning them. This output isn't JSON, and includes HTML markup. This is being sent as part of the result of your webhook and will cause what is returned to be invalid.
Update
Based on your latest code, there are still many logical, and a few syntactical, problems.
A "500 Internal Server Error" indicates that your program didn't run correctly and crashed for some reason. As posted, it is missing a closing }, which could be the problem if that isn't in your actual code.
Even if you fix that, there are many issues with the code:
It isn't clear what you intend to do with the results of calling your "test1" script. You store them in $data and don't do anything with it.
You're calling the other website (test1) before you look at what the user has asked you to do. Which is fine, but then why do you care what the user is asking you?
Original Answer
There are a few errors here, but the underlying problem is that you're mixing up where things run and the capabilities of the caller to your webhook.
For a Dialogflow webhook, Google/Dialogflow is sending JSON (which you seem to be handling ok), and expecting back JSON. Although it looks like you send this back as part of send_message(), you're also sending something back when you call connexion(). What you're sending back in this case is not JSON, but HTML with JavaScript.
Which leads to the second problem - If this was php that was generating an HTML page that included a script, you'd be in fine shape. But it isn't. You have to send back only JSON.
You can do something like this to call the other API and get back the contents:
$body = file_get_contents("http://google-home.exhalia.fr/test1");
Which will set $body to the body of the page you've called. What you do with that, at that point, is up to you. But you need to make this call before your call to send_message() because you want to represent the contents as part of what you're saying.
(See How to send a GET request from PHP? for a discussion of other methods available to you in case you need to do a POST, use header information, etc.)

Related

Symfony 5.* + Guzzle : cookies persistence

I'm currently developping an application in Symfony using Guzzle. I succesfully created a service where I make my requests (one request to get a list of enterprises, another to get user infos, ...) but I have issues regarding cookies in Guzzle. I've got to say I'm a newbie regarding API so I'm learning as I read the documentation but found nothing interesting for the moment. I've tried everything found on the internet so far but didn't get the result I wanted.
When I make a request, I get a property "Set-Cookie" in my response that I need to put in my next requests. The "Set-Cookie" property is something like "EfficySession=XX-XXXXX~XXXXXXXX-XXXXXXXX; path=/crm/; expires=Wed, 13 Oct 2021 23:22:14 GMT; HttpOnly".
So far this is where I am :
I create my client in the construct in order to be able to use the same client in every method :
public function __construct()
{
$this->client = new Client(["base_uri" => "BASE_URI", "allow_redirect" => true]);
}
And this is my test request to try setting my cookies right :
public function testFunction()
{
$json = json_encode([
[
"#name" => "api",
"#func" => [
[
"#name" => "currentuserfullname"
]
]
]
]);
$jar = new CookieJar();
$headers = [
'X-Efficy-ApiKey' => $this->apiKey,
'X-Efficy-Logoff' => 'false',
'Content-Type' => 'application/json'
];
$options = ["headers" => $headers, "body" => $json, "cookies" => $jar];
$response = $this->client->request('GET', 'json', $options);
$cookieParser = new SetCookie();
$cookie = $cookieParser->fromString($response->getHeader("Set-Cookie")[0]);
$cookie->setDomain('DOMAIN');
$this->jar->setCookie($cookie);
return json_decode($response->getBody()->getContents())[0]->{'#func'}[0];
}
But my cookies doesn't seem to be stored since I always get the property "Set-Cookie" in my response's headers... I think I've tried everything, from using SessionCookieJar to using CookieJar but nothing seems to be working.
Maybe I don't understand things the right way but as I said above, I'm just starting with API so sorry if you see big mistakes in my code.

Return a JSON object in the body of a HTTPS response

I have a OAUTH 2.0 Server, and i have succesfully implemented it up to the last level using PHP
Reference Link : https://developers.google.com/actions/identity/oauth2-code-flow
However, im am on the Last Step now which says
---> Return the following JSON object in the body of the HTTPS response
{
token_type: "bearer",
access_token: "ACCESS_TOKEN",
refresh_token: "REFRESH_TOKEN",
expires_in: SECONDS_TO_EXPIRATION
}
I have done the following
$json = array(
'token_type:' => "bearer",
'access_token:' => $ACCESS_TOKEN,
'refresh_token:' => $REFRESH_TOKEN,
'expires_in:' => '3600'
);
$jsonstring = json_encode($json);
echo $jsonstring;
die();
In which $ACCESS_TOKEN and $REFRESH_TOKEN and two variables containing the necessary information.
My Question is how do i return the 'JSON object in the body of the HTTPS response: '?
Would mean a lot if anyone can help me figure this outThanks in Advance!
Please visit this site, and see you might understand what i'm trying to do then :) https://developers.google.com/actions/identity/oauth2-code-flow
Most of your action appears to be correct. Sending JSON as the body requires two steps.
First, you must set the content-type header to indicate the body is JSON. You must do this before any other data, including blank lines, are output. Having this right after the PHP header on the page is probably good practice to make sure nothing else included generates this. This header is done as something like
<?php
header("Content-type:application/json");
The rest of your code looks correct. Sending a "JSON Object" means sending a specifically formatted text representation of the data. That formatting is done through json_encode().
$json = array(
'token_type:' => "bearer",
'access_token:' => $ACCESS_TOKEN,
'refresh_token:' => $REFRESH_TOKEN,
'expires_in:' => '3600'
);
$jsonstring = json_encode($json);
echo $jsonstring;

PHP SoapRequest: get response

I am trying to implement a soaprequest and making the call does seem to work. The only problem is: I don't know how to receive the response data. My code looks like this:
$auth = array(
'UsernameToken' => array(
'Username' => 'xxx',
'Password' => 'yyyy'
)
);
$header = new SoapHeader('xs','Security',$auth, 0);
$client->__setSoapHeaders($header);
$client->__setLocation('http://example.com/test.php');
$params = array(
...
'trace' => 1,
'cache_wsdl' => 0
);
try {
$response = $client->getSomeData($params);
}catch(Exception $e){
echo "Exception: ".$e->getMessage();
}
print_r($response);
This results in an empty page, because $response is empty. But the test.php file is called (I tried with a simple mail() command and it sends the mail every time I call the page with the soapclient).
So I guess the soap response is somehow sent to the test.php file - right? How do I get it? If I do not set the location, I get a nullpointerexception, so I have to do that. I tried
$client->__getLastResponse()
that's empty too.
What can I do, how do I get the soap response data? Any hints would be appreciated. Thank you!

How to add form data on Post requests for Buzz HTTP Client on Laravel?

I'm using Buzz HTTP Client for Laravel.
I have a problem adding form data to my POST requests, since it wasn't specified in it's wiki/documentation.
Listed below are the two ways of sending requests.
Example 1:
$response = Buzz::post('http://api.website.com/login');
//how do I add a "username", and "password" field in my POST request?
echo $response;
echo $response->getContent;
Example 2:
$request = new Buzz\Message\Request('POST', '/', 'http://google.com');
$response = new Buzz\Message\Response();
//how do I add a "username", and "password" field in my POST request?
$client = new Buzz\Client\FileGetContents();
$client->send($request, $response);
echo $request;
echo $response;
The answer here is going to really depend on what the API expects. Lets assume, the API expects the password and username sent as JSON in the content of the request. The example http request would look something like:
POST /login HTTP/1.1
Content-Type: application/json
{
"username": "bugsBunny",
"password": "wh4tsUpD0c"
}
To do this with Buzz, this should work:
$jsonPayload = json_encode([
‘username’ => ‘bugsBunny’,
‘password’ => ‘wh4tsUpD0c
]);
$headers = ['Content-Type', 'application/json'];
$response = Buzz::post('http://api.website.com/login', $headers, $jsonPayload);
If you're attempting to submit a form on a given website, you shouldn't use the above method. Instead use Buzz's built in form method which will attach the correct headers.
use Buzz\Message\Form;
$request = new Form(Form::METHOD_POST, ‘login’, ‘api.website.com’);
$request->setFields([
‘username’ => ‘bugsBunny’,
‘password’ => ‘wh4tsUpD0c’
]);
$response = new Buzz\Message\Response();
$client = new Buzz\Client\Curl();
$client->send($request, $response);
On a side note, I'd suggest not using this library. The library is, as you stated, Laravel integration for Buzz. The issue here is, the author should have made buzz a dependency listed in composer, rather than include the Buzz source directly. This prevents updates to Buzz from making their way into this project. You can see on the actual Buzz repo, the last commit was 29 days ago. Also if another package is using Buzz and including it correctly by composer, composer would install both packages. But when an instance of Buzz was created, you couldn't be certain which version was being loaded. You should just use Buzz, which can be found on packagist.
// assuming $headers and $jsonPayload are the same as in previous example.
$browser = new Buzz\Browser();
$response = $browser->post('http://api.website.com/login', $headers, $jsonPayload);
It was foolish of me to not read the code first before asking.
The form data is actually pased on the third parameter for the function. Though it accepts strings only so don't forget to json encode your data.
Buzz Class
public function post($url, $headers = array(), $content = '')
{
....
....
}
Buzz::post($url, array(), json_encode(array('Username'=>'usernamexx','Password'=>'p#$$w0rD')) );

"Login Required" when creating Google Calendar event via PHP cURL?

I've found this question numerous times, but I can't find a single instance of a solution, so I'm trying myself.
I'm creating a simple web application to help my employer schedule events to a Google Calendar. I've created the calendar, registered it with the Google API and have written cURL functions to check for existing appointments and return times & dates. I'm hung up on the function to create new events. The function I've written (with some variable names expanded for clarity) follows:
function post_cal($url, $header, $post_content)
{
global $authtoken, $curlDefaults;
$request = $url;
$headers = array('Content-Type: application/json; Authorization: OAuth ' . $authtoken . $header);
$options = array (
CURLOPT_URL => $request,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $post_content,
);
$ch = curl_init();
curl_setopt_array($ch, ($curlDefaults + $options));
$result = curl_exec($ch);
curl_close($ch);
$json = json_decode($result, true);
return $json;
}
I get a "401 - Login Required" error object when I try to run the post_cal function like so:
$scheduled = post_cal('https://www.googleapis.com/calendar/v3/calendars/xxxxxx/events, '', $apptInfo);
The cURL function is almost identical to the functions I have in place to read events & return existing values - both of which work fine! I use the same $authtoken variable, collected via a refresh token with the "https://www.googleapis.com/auth/calendar" scope explicitly defined. I have read and re-read the Google OAuth documentation but can't seem to find exactly where this error is coming from.
$apptInfo is an array, encoded to JSON, with the appointment information and includes a start & end time, summary and description.
I know this can be done more easily with the PHP library provided by Google, or with the Zend/GData framework. However, I am using this project as a way to teach myself PHP - I have very little experience with it prior to now - and would like to at least understand where the Login error is coming from, and how I might overcome it, before falling back on existing shortcuts. I have the luxury of time on my side since this is not a necessary project; it's just something I'm trying to help out with.
Can anyone explain to me what I'm doing wrong, or what further information I'd need to share to isolate the issue? I'd hate to miss this as a learning opportunity!
Thanks!
Using firebug you can exactly see the headers of what you are sending. I guess is a debugging problem because all seems to be fine. But i recommend using the PHP API SDK from google.
$events = $service->events->listEvents('primary');
while(true) {
foreach ($events->getItems() as $event) {
echo $event->getSummary();
}
$pageToken = $events->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$events = $service->events->listEvents('primary', $optParams);
} else {
break;
}
}
https://developers.google.com/google-apps/calendar/v3/reference/events/list

Categories