Amazon Lex postContent error "Failed to decode Session attributes." - php

I am attempting to connect my webpage to my Lex bot using postContent from the AWS SDK for PHP.
I set the credentials and arguments then attempt postContent. Here is the relevant code:
$credentials = new \Aws\Credentials\Credentials('XXXXXXXX', 'XXXXXXXXXXXXXXXXXXXXXXXXXX');
$args = array(
'region' => 'us-east-1',
'version' => 'latest',
'debug' => true,
'credentials' => $credentials
);
$lex_client = new Aws\LexRuntimeService\LexRuntimeServiceClient($args);
$lex_response = $lex_client->postContent([
'accept' => 'text/plain; charset=utf-8',
'botAlias' => 'XXXX',
'botName' => 'XXXX',
'contentType' => 'text/plain; charset=utf-8',
'inputStream' => $userInput,
'requestAttributes' => "{}",
'sessionAttributes' => "{}",
'userId' => 'XXXXXXXXXXXX',
]);
This errors with:
'Error executing "PostContent" on "https://runtime.lex.us-east-1.amazonaws.com/bot/XXXX/alias/XXXX/user/XXXXXXXXXX/content";
AWS HTTP error: Client error: POST https://runtime.lex.us-east-1.amazonaws.com/bot/XXXX/alias/XXXX/user/XXXXXXXXXX/content resulted in a 400 Bad Request response:
{"message":"Invalid Request: Failed to decode Session attributes. Session Attributes should be a Base64 encoded json map of String to String"}' (length=142)
I have attempted using all kinds of JSON strings, JSON encoded strings, and Base64 encoded strings in the sessionAttributes but I continue to get this same error.

The LexRuntimeService in the AWS SDK automatically JSON encodes and Base64 encodes the postContent array. By passing it a JSON string, the json encoding in the SDK will place double quotes around the {} making it "{}" and that causes the error.
So simply pass the sessionAttributes and requestAttributes as PHP arrays.
$lex_response = $lex_client->postContent([
'accept' => 'text/plain; charset=utf-8',
'botAlias' => 'XXXX',
'botName' => 'XXXX',
'contentType' => 'text/plain; charset=utf-8',
'inputStream' => $userInput,
'requestAttributes' => array(),
'sessionAttributes' => array(), // <---- PHP Array not JSON
'userId' => 'XXXXXXXXXXXX',
]);

Related

Laravel posting base64 file via HTTP client is not working

I'm implementing third party API in Laravel where I have to send some data along with fileData with base64.
Like this:
To post the data I'm sending like this:
$requestUrl = $this->baseUrl . $endpoint;
$content = [
'associatedType' => 'property',
'associatedId' => 'XXXXXXX81',
'typeId' => 'DET',
'name' => '304-Smithson-Road-Details.pdf',
"isPrivate" => false,
'fileData' => 'data:application/pdf;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=='
];
$response = Http::withHeaders([
"api-version" => config("apiVersion"),
"customer" => config("customer"),
"Accept" => "application/json-patch+json",
"Authorization" => "Bearer {$this->token}"
])->send($method, $requestUrl, [
"body" => json_encode($content)
])->collect()->toArray();
return $response;
After executing the above code I'm getting null response and file is not uploaded.
Is there any mistake in HTTP request code?

How to send data to CloudFlare API?

I'm trying to delete files from my CloudFlare cache using PHP. Using Guzzle I've done this:
$client = new \GuzzleHttp\Client;
$response = $client->delete('https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache', [
'query' => [
'files' => 'https://example.com/styles.css,
],
'headers' => [
'X-Auth-Email' => 'myemail',
'X-Auth-Key' => 'myapikey',
],
]);
But when I run this I get an error:
Client error: DELETE https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache?files=https%3A%2F%2Fexample.com/etc resulted in a 400 Bad Request response: {"success":false,"errors":[{"code":1012,"message":"Request must contain one of \"purge_everything\", \"files\", \"tags\" (truncated...)
I can't get it to work using Postman either. I put in the required headers and try to set a key of files or files[] with the URL but it doesn't work. I've also tried data with raw JSON as the value like {"files":["url"]} (along with a JSON content-type header) but get the same error. It thinks I'm not sending the files key.
The method for purge_cache is POST instead of DELETE (Source: https://api.cloudflare.com/#zone-purge-files-by-url).
The payload is not sent as 'query', but as 'json'.
Files should be an array, not a string.
So the correct syntax should be....
$client = new \GuzzleHttp\Client;
$response = $client->post('https://api.cloudflare.com/client/v4/zones/myzoneid/purge_cache', [
'json' => [
'files' => ['https://example.com/styles.css'],
],
'headers' => [
'X-Auth-Email' => 'myemail',
'X-Auth-Key' => 'myapikey',
],
]);

POSTing JSON with GuzzleHttp\Client: returning 401 Unauthorized error

I'm trying to create a wrapper for a payment gateway api. I've chosen to use GuzzleHttp. Here is the basic code that I currently have. As the gateway expects input to be JSON formatted sent via HTTP POST, I tried two possible ways:
Using the json option and assigning a key-based array to it.
Explicitly setting content-type to application/json and sending a json formatted string via body.
Code:
$client = new Client([
'base_uri' => 'https://sandbox.gateway.com',
]);
$input = [
'merchant_id' => '12345-33445',
'security_key' => '**********',
'operation' => 'ping',
];
$clientHandler = $client->getConfig('handler');
$tapMiddleware = Middleware::tap(function ($request) {
foreach($request->getHeaders() as $h=>$v){
echo $h . ': ' . print_r($v) . PHP_EOL;
}
});
try {
$response = $client->post(
'/pg/auth',
[
'timeout' => 30,
'headers' => [
'Content-Type' => 'application/json',
'Cache-Control' => 'no-cache',
],
'body' => json_encode($input),
'debug' => true,
'handler' => $tapMiddleware($clientHandler)
]
);
print_r($response);
} catch(Exeption $e){
print_r($e);
}
Unfortunately, gateway got back with a 401 error although the credentials are correct. I suspect the way request is sent has an issue. I came to this conclusion as the headers printed from within the tap function are all arrays (especially content-type) instead of strings. Unlike what is described here http://guzzle.readthedocs.org/en/latest/request-options.html?highlight=request#json.
Array
(
[0] => GuzzleHttp/6.1.1 curl/7.43.0 PHP/5.5.29
)
User-Agent: 1
Array
(
[0] => sandbox.gateway.com
)
Host: 1
Array
(
[0] => application/json
)
Content-Type: 1
How about sending the request as suggested?
$client = new Client([
'base_uri' => 'https://sandbox.gateway.com',
]);
$client->request('POST', '/pg/auth', [
'timeout' => 30,
'debug' => true,
'json' => [
'merchant_id' => '12345-33445',
'security_key' => '**********',
'operation' => 'ping',
],
]);
For reference, see http://docs.guzzlephp.org/en/latest/request-options.html#json.

Can you include raw JSON in Guzzle POST Body?

This should be soo simple but I have spent hours searching for the answer and am truly stuck. I am building a basic Laravel application and am using Guzzle to replace the CURL request I am making at the moment. All the CURL functions utilise raw JSON variables in the body.
I am trying to create a working Guzzle client but the server is respsonding with 'invalid request' and I am just wondering if something fishy is going on with the JSON I am posting. I am starting to wonder if you can not use raw JSON in the Guzzle POST request body? I know the headers are working as I am receiving a valid response from the server and I know the JSON is valid as it is currently working in a CURL request. So I am stuck :-(
Any help would be sooo greatly appreciated.
$headers = array(
'NETOAPI_KEY' => env('NETO_API_KEY'),
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'NETOAPI_ACTION' => 'GetOrder'
);
// JSON Data for API post
$GetOrder = '{
"Filter": {
"OrderID": "N10139",
"OutputSelector": [
"OrderStatus"
]
}
}';
$client = new client();
$res = $client->post(env('NETO_API_URL'), [ 'headers' => $headers ], [ 'body' => $GetOrder ]);
return $res->getBody();
You can send a regular array as JSON via the 'json' request option; this will also automatically set the right headers:
$headers = [
'NETOAPI_KEY' => env('NETO_API_KEY'),
'Accept' => 'application/json',
'NETOAPI_ACTION' => 'GetOrder'
];
$GetOrder = [
'Filter' => [
'OrderID' => 'N10139',
'OutputSelector' => ['OrderStatus'],
],
];
$client = new client();
$res = $client->post(env('NETO_API_URL'), [
'headers' => $headers,
'json' => $GetOrder,
]);
Note that Guzzle applies json_encode() without any options behind the scenes; if you need any customisation, you're advised to do some of the work yourself
$res = $client->post(env('NETO_API_URL'), [
'headers' => $headers + ['Content-Type' => 'application/json'],
'body' => json_encode($getOrders, ...),
]);
Guzzle 7 Here
The below worked for me with raw json input
$data = array(
'customer' => '89090',
'username' => 'app',
'password' => 'pwd'
);
$url = "http://someendpoint/API/Login";
$client = new \GuzzleHttp\Client();
$response = $client->post($url, [
'headers' => ['Content-Type' => 'application/json', 'Accept' => 'application/json'],
'body' => json_encode($data)
]);
print_r(json_decode($response->getBody(), true));
For some reasons until I used the json_decode on the response, the output wasn't formatted.
You probably need to set the body mime type. This can be done easily using the setBody() method.
$request = $client->post(env('NETO_API_URL'), ['headers' => $headers]);
$request->setBody($GetOrder, 'application/json');

How do i update object using php-sdk? (The parameter object is required)

$response = $facebook->api(
'me/objects/namespace:result',
'POST',
array(
'app_id' => app_id,
'type' => "namespace:result",
'url' => "http://samples.ogp.me/370740823026684",
'title' => "Sample Result",
'image' => "https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png",
'description' => ""
)
);
I get the following error.
The parameter object is required
I don't know where to add the parameter object.
I have been facing the same issue for the past couple of days, in the end I stopped trying to use the Facebook PHP SDK to send the request and resorted to using just sending a HTTP Request.
I am creating an object rather than updating one, but the implementation shouldn't differ much from your needs. I was getting the same error (The parameter object is required) and the below implementation resolved that issue.
I used the vinelab HTTP client composer package and built a request like this:
$request = [
'url' => 'https://graph.facebook.com/me/objects/namespace:object',
'params' => [
'access_token' => $fbAccessToken,
'method' => 'POST',
'object' => json_encode([
'fb:app_id' => 1234567890,
'og:url' => 'http://samples.ogp.me/1234567890',
'og:title' => 'Sample Object',
'og:image' => 'https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png',
'og:description' => 'Sample Object'
])
]
];
// I'm using Laravel so this bit might look different for you (check the vine lab docs if you use that specific HTTP client)
$response = HttpClient::post($request);
// raw content
$response->content();
// json
$response->json();
As I said, I used the vinelab HTTP package in my implementation, you should be able to use any similar package or directly use curl in PHP instead.

Categories