Guzzle 422 Unprocessable Entity error - php

I'm using browserstack screenshots API - https://www.browserstack.com/screenshots/api The following curl is working:
curl -u "username:password" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"browsers": [{"os": "Windows", "os_version": "7", "browser_version": "8.0", "browser": "ie"}], "url": "http://google.com"}' http://www.browserstack.com/screenshots
However, when I try the same call call with guzzle I get 422 Unprocessable Entity error.
$client = new GuzzleHttp\Client();
$request = $client->post('http://www.browserstack.com/screenshots', [
'headers' => ['Content-type' => 'application/json'],
'auth' => ['username', 'password']
]
);
$data = ['browsers' => ['os' => 'Windows', 'os_version' => '7', 'browser_version' => '8.0', 'browser' => 'ie'], 'url' => 'http://google.com'];
$request->setBody($data);
$response = $request->send();
dd($response);
Can you suggest how to debug this issue?

I had a mistake in method. It should be $client->createRequest instead of $client->post
Also, I had a mistake in data being passed. Browsers should be array of arrays
There is another library that could be used with browserstack and guzzle: https://github.com/ksenzee/browserstack-screenshots-php
$client = new GuzzleHttp\Client();
$request = $client->createRequest('POST', 'http://www.browserstack.com/screenshots', [
'headers' => ['Content-type' => 'application/json'],
'auth' => ['user', 'pwd'],
'body' => '{"browsers": [
{"os": "Windows", "os_version": "7", "browser_version": "8.0", "browser": "ie"},
{"os": "android", "os_version": "4.4", "device": "HTC One M8", "browser": "Android Browser"}
],
"url": "http://www.lipsum.com"}'
]
);
$response = $client->send($request);
dd($response->json());

To send JSON to the Screenshots API, you would need to format it as a JSON string.
$client = new GuzzleHttp\Client();
$request = $client->post('http://www.browserstack.com/screenshots', [
'headers' => ['Content-type' => 'application/json'],
'auth' => ['username', 'access_key'],
'body' => '{"browsers": [
{"os": "Windows", "os_version": "7", "browser_version": "8.0", "browser": "ie"},
{"os": "android", "os_version": "4.4", "device": "HTC One M8", "browser": "Android Browser"}
],
"url": "http://www.lipsum.com"}'
]
);
You will then be able to view the progress on your BrowserStack Screenshots page.
For a guide on how to send POST requests using Guzzle, you can refer this documentation — https://media.readthedocs.org/pdf/guzzle/latest/guzzle.pdf.

In my case uses 'json' in options's argument (https://es.stackoverflow.com/questions/185183/porqu%C3%A9-guzzle-5-0-lanza-el-error-422-si-estoy-armando-bien-la-consulta#185192), example:
$client = new GuzzleHttp\Client(['base_url' => 'http://www.browserstack.com/']);
$request = $client->post('screenshots', [
'headers' => ['Content-type' => 'application/json'],
'auth' => ['username', 'access_key'],
'json' => '{"browsers": [
{"os": "Windows", "os_version": "7", "browser_version": "8.0", "browser": "ie"},
{"os": "android", "os_version": "4.4", "device": "HTC One M8", "browser": "Android Browser"}
],
"url": "http://www.lipsum.com"}'
]
);

Related

How to send dynamic template mail via guzzle HTTP in PHP

I'm trying to send an email via Dynamic template in SendGrid using Guzzle HTTP in PHP.
But I was not able to send mail. As I get only the error like below without any reason in it.
Type: GuzzleHttp\Exception\ClientException
Message: Client error: `POST https://api.sendgrid.com/v3/mail/send` resulted in a `400 Bad Request` response: {"errors":[{"message":"Bad Request","field":null,"help":null}]}
My PHP example code:
require __DIR__.'../../vendor/autoload.php';
$CLIENT = new GuzzleHttp\Client();
$response = $CLIENT->request('POST', 'https://api.sendgrid.com/v3/mail/send', [
"headers" => [
"Authorization" => "Bearer my-api-key",
"Content-Type" => "application/json"
],
'data' => '{
"from": {
"email": "admin#example.com"
},
"personalizations": [{
"to": [{
"email": "me#gmail.com"
}],
"dynamic_template_data": {
"email_data": [{
"id": "2",
"title": "Artificial Intelligence in Health Care",
"image": "https://example.com//uploads/3663581583995181_0724.jpg",
"description": "Immediate application of AI in the Health Care domains."
}, {
"id": "199",
"title": "Aesthetics Skill Discussion 3 by Jranand",
"image": "",
"description": "Aesthetics Skill Discussion 3 by Jranand"
}]
}
}],
"template_id": "my-template-id"
}',
]);
echo $response->getStatusCode();
I was able to send an email via the dynamic template test method in SendGrid with the same dynamic_template_data. But trying this with Guzzle HTTP. I m not able to find the reason for the error.
Able to send an email with dynamic JSON data in the testing.
Can anyone help me out to solve the problem?
Thanks in advance.
There is no data request option in json, you need to change your code either you can use json request option from guzzle(will need lesser effort) or you can directly right your body.
try{
$CLIENT = new GuzzleHttp\Client();
$data = [
"from" => [
"email" => "admin#example.com"
],
"personalizations" => [
[
"to" => [
[
"email" => "me#gmail.com"
]
],
"dynamic_template_data" => [
"email_data" => [
[
"id" => "2",
"title" => "Artificial Intelligence in Health Care",
"image" => "https://example.com//uploads/3663581583995181_0724.jpg",
"description"=> "Immediate application of AI in the Health Care domains."
],
[
"id" => "199",
"title" => "Aesthetics Skill Discussion 3 by Jranand",
"image" => "",
"description" => "Aesthetics Skill Discussion 3 by Jranand"
]
]
]
]
],
"template_id" => "my-template-id"
];
$response = $CLIENT->request('POST', 'https://api.sendgrid.com/v3/mail/send', [
"headers" => [
"Authorization" => "Bearer my-api-key",
"Content-Type" => "application/json"
],
'json' => $data,
]);
if ($guzzleResponse->getStatusCode() == 200) {
$response = json_decode($guzzleResponse->getBody(),true);
//perform your action with $response
}
}
catch(\GuzzleHttp\Exception\RequestException $e){
// you can catch here 400 response errors and 500 response errors and log those errors
}catch(Exception $e){
//other errors
}

How to make curl request by passing raw data to post method?

I have an API. In this API, I pass X-AUTH_TOKEN & X-AUTH-KEY as headers and in the body, I pass raw array data ["1", "2", "3"....]
I have tested it using postman, it is returning me response.
But when I implement it using symfony, I am getting HTTP/2 404 returned for "
This is what I have implemented in Symfony.
$response = $this->httpClient->request('POST', $url, [
'headers' => [
'x-auth-token' => $authToken,
'x-auth-key' => $authKey
],
'body' => [
"1",
"2",
"3",
"4",
]
]);
Can anybody please help me how can I implement?
Thank You.
Instead of body pass json
$response = $this->httpClient->request('POST', $url, [
'headers' => [
'x-auth-token' => $authToken,
'x-auth-key' => $authKey
],
'body' => [
"1",
"2",
"3",
"4",
]
]);

Hot to send a nested json post request with cURL and PHP

I must send a post request with the following json data structure using PHP and cURL:
{
"assistanceRequest":
{
"type": "TECHNICAL_DATA",
"deliveryMode": "NORMAL",
"creationDate": "2020-04-09T10:09:00+02:00",
"source": "ATD",
"language": "FR",
"country": "FR"
},
"customer":
{
"code": 123456,
"login": "client#company.com",
"companyName": "Workshop Harris",
"phoneNumber": "+44 123456789",
"email": "workshop#company.com"
},
}
However I don't understand how to create a similar request. I tried with the following code but I suppose it's not correct because I should group the data in two blocks:
$post = [
'type' => 'TECHNICAL_DATA',
'deliveryMode' => 'NORMAL',
'creationDate' => '2020-04-16T12:46:33+02:00',
'source' => 'ATD',
'language' => 'FR',
'country' => 'CH',
'code' => '123456',
'login' => 'FR1234561A',
'companyName' => 'Workshop Harris Love',
'phoneNumber' => '+390432561543',
'email' => 'client#client.com', ];
$post_encoded = json_encode($post);
$ch = curl_init('http://222.333.333.444/opafffws/public/api/req');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_encoded);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($post_encoded))
);
$response = curl_exec($ch);
echo "The response 1: <br>" . $response;
echo "<br>";
curl_close($ch);
Can help?
<?php
$data = [
'assistanceRequest' => [
'type' => 'TECHNICAL_DATA',
'deliveryMode' => 'NORMAL',
"creationDate" => "2020-04-09T10:09:00+02:00",
"source" => "ATD",
"language" => "FR",
"country" => "FR"
],
'customer' => [
"code" => 123456,
"login" => "client#company.com",
"companyName" => "Workshop Harris",
"phoneNumber" => "+44 123456789",
"email" => "workshop#company.com"
],
];
echo "<pre>"; print_r(json_encode($data));
This is an example for your structure. Tweak it as you need.
The output of the above code will be:
{
"assistanceRequest": {
"type": "TECHNICAL_DATA",
"deliveryMode": "NORMAL",
"creationDate": "2020-04-09T10:09:00+02:00",
"source": "ATD",
"language": "FR",
"country": "FR"
},
"customer": {
"code": 123456,
"login": "client#company.com",
"companyName": "Workshop Harris",
"phoneNumber": "+44 123456789",
"email": "workshop#company.com"
}
}

Laravel function return me just NULL

I need to connect to an API to claim a voucher. At API doc I see:
POST /api/v1/vouchers/{voucherId}/claim
{
"Participant": {
"FirstName": "John",
"LastName": "James,
"Telephone": "08456 127 127",
"EmailAddress": "tim#asdasd.net",
"PostCode": "ASD 9HX",
"HouseNameNumber": "2",
"Street": "Bridge Road2",
"Locality": "LONDON",
"Town": "Aylesbury",
"County": "Bucks"
},
"ExperienceDate": "2017-10-01T00:00:00"
}
Based on this I write my function using Laravel framework:
public function testclaim()
{
$client = new GuzzleHttp\Client;
$headers = ['Content-Type' => 'application/json'];
try {
$res = $client->post('https://api.example.com/api/v1/vouchers/244775_2-H8SC/claim', [
'headers'=>$headers,
'auth' => [
'JAMES-JJ', 'ajhsdajsdhaj32423'
],
'json' => [
'Participant' => [
"FirstName"=> "asdasd",
"LastName"=> "asdasd",
"Telephone"=> "08456 127 127",
"EmailAddress"=> "tim#asdasd.net",
"PostCode"=> "HP18 9HX",
"HouseNameNumber"=> "1",
"Street"=> "Bridge Road",
"Locality"=> "Ickford",
"Town"=> "Aylesbury",
"County"=> "Bucks"
],
'ExperienceDate' => '2017-11-01T00:00:00'
]
]);
$res = json_decode($res->getBody()->getContents(), true);
return response()->json(['data' => $res]);
//dd($res);
}
catch (GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
$result = json_decode($response->getBody()->getContents());
return response()->json(['data' => $result]);
}
}
Now when I run this function I just get:
{"data":null}
ANybody see what is wrong in my code?
How to solve this issue?
I also try without header to send a request but again I get the same response from API.
You don't need getContents() if you want to convert the body to an Array.

Laravel 5 - make https guzzle request with form_param

I need to make a POST request to claim voucher. At API docs I find this:
POST /vouchers/{voucherId}/claim
{
"Participant": {
"FirstName": "John",
"LastName": "Jones",
"Telephone": "99999 127 127",
"EmailAddress": "hahahah#hahaha.net",
"PostCode": "HP18 9HX",
"HouseNameNumber": "2",
"Street": "Bridge Road",
"Locality": "Ickford",
"Town": "Lodnon",
"County": "Bucks"
},
"ExperienceDate": "2015-10-01T00:00:00"
}
Now I, using Laravel guzzle library I make this request:
public function testclaim()
{
$client = new GuzzleHttp\Client;
$headers = ['Content-Type' => 'application/json'];
$res = $client->post('https://apidev.asdasd.com/vouchers/11989898_1-9FDD/claim', [
'headers'=>$headers,
'auth' => [
'PET_RES', 'asdasdasd111111'
],
'form_params' => [
'FirstName' => 'Peter',
'LastName' => 'Alexo',
'Telephone' => '8888888888888'
]
]);
$res = json_decode($res->getBody()->getContents(), true);
dd($res);
}
but what I get is:
400 Bad Request
{ "Message": "The request is invalid.", "ModelState": { "claim": [ "An
error has occurred." ] (truncated...)
What is the right way to send a request to the API with following data?
try this
...
'form_params' => [
'Participant' => [
'FirstName' => 'Peter',
'LastName' => 'Alexo',
'Telephone' => '8888888888888'
],
'ExperienceDate' => '2015-10-01T00:00:00'
]
...
if your api just accept json, try replace form_params with json

Categories