Convert cURL to Guzzle POST with --form-params and --header - forms

I'm struggling with a given curl-request which I want to handle over guzzle.
The curl-request looks like this:
curl --location --request POST "https://apis.myrest.com" \
--header "Content-Type: multipart/form-data" \
--header "Authorization: Bearer YOUR-BEARER-TOKEN" \
--form "mediaUrl=https://myfile.mpg" \
--form "configuration={
\"speechModel\": { \"language\": \"en-US\" },
\"publish\": {
\"callbacks\": [{
\"url\" : \"https://example.org/callback\"
}]
}
}
And I want it to send via guzzle like that:
// 1. build guzzle client:
//----------------------------------------------------------------------
$this->client = new Client([
'base_uri' => $this->config->getBaseUri(),
]);
// 2. build guzzle request:
//----------------------------------------------------------------------
$request = new Request(
'POST',
'myendpoint',
[
'authorization' => 'Bearer ' . $this->config->getApiToken(),
'cache-control' => 'no-cache',
'content-type' => 'application/json',
// maybe here, or not?
form_params => ['mediaUrl' => 'www.media.com'],
]
);
// 3. send via client
//----------------------------------------------------------------------
response = $this->client->send($request, ['timeout' => self::TIMEOUT]);
My problem now is, that I have no clue how to handle this. In guzzle's documentation i found "form_params":
http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request#post-form-requests
But it does not seem to work. If I add the form_params-array to my request, the receiver does not get them. Can anybody tell me, how to write the exact curl-command with guzzle?
Thanks

Try using multipart instead of form_params.
http://docs.guzzlephp.org/en/latest/request-options.html#form-params
From Guzzle documentation:
form_params cannot be used with the multipart option. You will need to
use one or the other. Use form_params for
application/x-www-form-urlencoded requests, and multipart for
multipart/form-data requests.
Additionally try setting Guzzle Client with debug on, as it will display raw HTTP request that it sends, so you can compare it more easily with the curl command.
http://docs.guzzlephp.org/en/latest/request-options.html#debug
It is difficult to understand what is the exact request you would like to send, because there is incosistencies between the curl example and your code. I tried to replicate the curl as best as I could. Please note that Request 3rd parameter only expects headers, and for request options you have to use the 2nd parameter of send.
$client = new Client([
'base_uri' => 'https://example.org',
'http_errors' => false
]);
$request = new Request(
'POST',
'/test',
[
'Authorization' => 'Bearer 19237192837129387',
'Content-Type' => 'multipart/form-data',
]
);
$response = $client->send($request, [
'timeout' => 10,
'debug' => true,
'multipart' => [
[
'name' => 'mediaUrl',
'contents' => 'https://myfile.mpg'
],
[
'name' => 'configuration',
'contents' => json_encode([
'speechModel' => [
'language' => 'en-US'
],
'publish' => [
'callbacks' =>
[
[
'url' => 'https://example.org/callback'
]
]
]
])
]
]
]);

Related

Symfony HttpClient, fail to authenticate external API witch Bearer

I have a problem, I try to use a external API, but the response of that APi is a 401.
1º- I send a request to get the auth token, works fine.
$auth = $this->client->request(
'POST',
'https://api.namebright.com/auth/token',
[
'body' => [
'grant_type' => 'client_credentials',
'client_id' => $clientID,
'client_secret' => $clientSecret,
],
]
);
2º- handler token, i dump the token is loocks fine
$token = sprintf('Bearer %s', $auth->toArray()['access_token']);
3º- I make other request to get the API response, i got a 401.
$response = $this->client->request(
'GET',
'http://api.namebright.com/rest/purchase/availability/google.pt',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => $token,
],
]
);
I don't know what i'm doing wrong. :(
I checked, for responses on the internet and i don't see the problem.
I Tried to change Authorization to authorization.
I tried to check the token in the postmen, works fine.

Call Rest Api Using Zend\Http\Client Or Guzzle

I am calling magento2 API in laravel. Using curl, I am getting correct response but I want to call API using GuzzleHttp\Client or Zend\Http\Client.
How can I call my api using this, below is my curl code snippet:
$curl = curl_init();
$data=array('username'=>$vendordata['merchant_name'],'password'=>$vendordata['password'],'customer'=>['email'=>$vendordata['email'],"firstname"=> $vendordata['firstname'], "lastname"=> $vendordata['lastname']],"addresses"=> ["region"=> $vendordata['address'], "region_id"=> 0],"default_shipping"=> true,"default_billing"=>true,"telephone"=>$vendordata['contact_number']);
$postdata=json_encode($data);
curl_setopt_array($curl, array(
CURLOPT_URL => "http://10.10.10.7/magento2/rest/V1/customers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $postdata,
CURLOPT_HTTPHEADER => array(
"authorization: OAuth oauth_consumer_key=\"sganfgvr2naxwmh21jgi5ffijuci0207\",oauth_token=\"d16pdq1avr1rs7h9745rc0x6py65a2vt\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1518006201\",oauth_nonce=\"4ghORA\",oauth_version=\"1.0\",oauth_signature=\"Ztq5ErznqvCl18GomWv0F55t5OA%3D\"",
"cache-control: no-cache",
"content-type: application/json",
"postman-token: 5ec55151-3365-7ffc-a6a4-ce5fe5bc451f"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
First, open the terminal and run this command to install Guzzle
composer require guzzlehttp/guzzle
Then add these lines to include guzzle in the specific controller.
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
Now, create a method you want to run to call the API and put the below code
$client = new Client(); //GuzzleHttp\Client
$result = $client->post('your-request-uri', [
'form_params' => [
'sample-form-data' => 'value'
]
]);
That's it!
Docs explain this pretty well : https://github.com/guzzle/guzzle
Here is the complete code when using guzzlehttp instead of curl
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'http://10.10.10.7/magento2/rest/V1/customers', array(
headers' => [
'Authorization' => 'OAuth oauth_consumer_key="sganfgvr2naxwmh21jgi5ffijuci0207",oauth_token="d16pdq1avr1rs7h9745rc0x6py65a2vt",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1518006201",oauth_nonce="4ghORA",oauth_version="1.0",oauth_signature="Ztq5ErznqvCl18GomWv0F55t5OA%3D',
'Cache-Control' => 'no-cache',
'Postman-Token' => '5ec55151-3365-7ffc-a6a4-ce5fe5bc451f'
],
'json' => $postdata
));
You also have to install following dependencies in your laravel project for PSR-7 support and look at this stackoverflow question as a reference:
composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros
That caused by you didn't define the Content-Type as application/json on HTTP Header. Please try this
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'http://10.10.10.7/magento2/rest/V1/customers', array(
headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'OAuth oauth_consumer_key="sganfgvr2naxwmh21jgi5ffijuci0207",oauth_token="d16pdq1avr1rs7h9745rc0x6py65a2vt",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1518006201",oauth_nonce="4ghORA",oauth_version="1.0",oauth_signature="Ztq5ErznqvCl18GomWv0F55t5OA%3D',
'Cache-Control' => 'no-cache',
'Postman-Token' => '5ec55151-3365-7ffc-a6a4-ce5fe5bc451f'
],
'json' => $postdata
));
And don't forget to load the dependencies using composer
composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

Default headers not applying to request

New to guzzle. I am trying to use it contact a REST endpoint. Sending the request via curl or using something like postman app for chrome it returns the expected JSON response. Sending it using guzzle below is returning a 404 error similar to what would be returned if I hit the URL without the headers inlcuded.
Why are the headers not making it into this request?
// Get extra detail for the object
$client = new \GuzzleHttp\Client([
'base_uri' => env('OPENIDM_URL'),
'headers' => [
'Content-Type' => 'application/json',
'X-OpenIDM-Username' => env('OPENIDM_USER'),
'X-OpenIDM-Password' => env('OPENIDM_PASS'),
'Authorization' => 'Basic Og=='
]
]);
$request = new \GuzzleHttp\Psr7\Request('GET', $attributes['sourceobjectid']);
$res = $client->send($request);
I have dumped the content of the client and request objects. They look as follows:
Client {#181 ▼
-config: array:8 [▼
"base_uri" => Uri {#188 ▼
-scheme: "https"
-userInfo: ""
-host: "my.url.here.com"
-port: null
-path: "/openidm"
-query: ""
-fragment: ""
}
"headers" => array:5 [▼
"Content-Type" => "application/json"
"X-OpenIDM-Username" => "myuser"
"X-OpenIDM-Password" => "mypass"
"Authorization" => "Basic Og=="
"User-Agent" => "GuzzleHttp/6.2.1 curl/7.38.0 PHP/5.6.26-0+deb8u1"
]
"handler" => HandlerStack {#169 ▶}
"allow_redirects" => array:5 [▶]
"http_errors" => true
"decode_content" => true
"verify" => true
"cookies" => false
]
}
Request {#189 ▼
-method: "GET"
-requestTarget: null
-uri: Uri {#190 ▼
-scheme: ""
-userInfo: ""
-host: ""
-port: null
-path: "managed/user/eb758aab-7896-4196-8989-ba7f97a7e962"
-query: ""
-fragment: ""
}
-headers: []
-headerNames: []
-protocol: "1.1"
-stream: null
Any suggestions would be much appreciated.
If you construct the request object yourself, Guzzle won't apply configurations to it.
You either have to use the convenience HTTP methods (get, put, etc) called from the client or use a custom middleware.
The first one is easier, the second one gives you more power, but responsibility too.

Facebook Messenger API Error: Payload cannot be empty for postback type button

I successfully set up Greeting Text, and now I trying to set up a payload for a Get Started button by this guide:
I send exactly:
curl -X POST -H "Content-Type: application/json" -d '{
"setting_type":"call_to_actions",
"thread_state":"new_thread",
"call_to_actions":[
{
"payload":"START"
}
]
}' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
but receive an error:
{"error":{"message":"(#100) Payload cannot be empty for postback type button","type":"OAuthException","code":100,"fbtrace_id":"GWv5XughbUQ"}}
What i do wrong?
Finally, I found my mistake. CBroe said I was wrong in request structure.
I used PHP and sent:
$requset = [
'call_to_actions' => [
'payload' => 'START'
],
'setting_type' => 'call_to_actions',
'thread_state' => 'new_thread'
];
But right form is:
$requset = [
'call_to_actions' => [
['payload' => 'START']
],
'setting_type' => 'call_to_actions',
'thread_state' => 'new_thread'
];

Facebook Messenger Bot, send Image Attachment

I'm creating a Facebook bot that has images uploaded to it, and it responds with an image. Can I send the image in an attachment and delete it off my server or do I have to send a URL to the image and keep the image on my server?
You can use their Upload API to upload your attachments to their servers.
curl -X POST -H "Content-Type: application/json" -d '{
"message":{
"attachment":{
"type":"image",
"payload":{
"url":"http://www.messenger-rocks.com/image.jpg",
"is_reusable":true,
}
}
}
}' "https://graph.facebook.com/v2.6/me/message_attachments?access_token=PAGE_ACCESS_TOKEN"
The upload call will respond back an attachment_id which can be used to send the attachment to the user without uploading it again.
curl -X POST -H "Content-Type: application/json" -d '{
"recipient": {
"id": "USER_ID"
},
"message": {
"attachment": {
"type": "image",
"payload": {
"attachment_id": "1745504518999123"
}
}
}
}' "https://graph.facebook.com/me/messages?access_token=PAGE_ACCESS_TOKEN"
curl \
-F recipient='{"id":"USER_ID"}' \
-F message='{"attachment":{"type":"image", "payload":{}}}' \
-F filedata=#/tmp/testpng.png \
"https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"
Here you can find an official example on how to atach a jpg or a png.
https://developers.facebook.com/docs/messenger-platform/send-api-reference#examples
I have the same problem, but still found no answer.
For now, the only way to send images with Facebook bot, is "image_url" with your's image url.
You can send attachments via the Facebook Messenger API by POSTing them directly (without using the payload.url option) with a multipart request. Here it is with PHP & Guzzle (though any good HTTP Request package should do, regardless of the scripting language):
use GuzzleHttp\Client;
$client = new Client();
$graphRequest = $client->request('POST', 'https://graph.facebook.com/v5.0/me/messages', [
'query' => [
'access_token' => $facebookInfo['pageAccessToken']
],
'multipart' => [
[
'name' => 'messaging_type',
'contents' => 'RESPONSE',
],
[
'name' => 'recipient',
'contents' => json_encode(['id' => $yourRecipientPSID]),
],
[
'name' => 'message',
'contents' => json_encode(['attachment' => ['type' => 'file', 'payload' => []]]),
],
[
'name' => 'filedata',
'contents' => fopen($yourFilePath, 'r'),
'filename' => $yourFileName,
],
],
]);
Note that the attachments.payload parameter is set, but null. The Graph API returns a 400 response if payload is not set.