I'm having trouble to pass the version parameter in a POST request using GuzzleHttp.
Client error: GET https://gateway.watsonplatform.net/tone-analyzer/api/v3/tone resulted in a 400 Bad Request response: {"code":400,"sub_code":"C00005","error":"Missing a minor version parameter in the URL. To use the latest version, add th (truncated...)
This is the latest I've tried:
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://gateway.watsonplatform.net/'
]);
$toneAnalyserResponse = $client->request('POST', 'tone-analyzer/api/v3/tone', [
'auth' => ['{username}', '{password}'],
'headers' => [
'Content-Type' => 'text/plain',
],
'form_params' => [
'version' => '2017-09-21',
'tone_input' => $text,
'sentences' => true
]
]);
This was failing too:
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://gateway.watsonplatform.net/'
]);
$toneAnalyserResponse = $client->request('POST', 'tone-analyzer/api/v3/tone', [
'auth' => ['{username}', '{password}'],
'headers' => [
'Content-Type' => 'text/plain',
],
'version' => '2017-09-21',
'tone_input' => $text,
'sentences' => true
]);
Failing as well if using GET instead of POST.
If I change the URI and add the version, then it works fine (well, it fails as it doesn't have the text to analyse in the request):
Change: tone-analyzer/api/v3/tone
To: tone-analyzer/api/v3/tone?version=2017-09-21
So, I guess the question is HOW DO YOU PASS URL PARAMETERS in a request using GuzzleHttp?
Note: my CURL command works fine (http 200):
curl -X POST -u "{username}":"{password}" --header 'Content-Type: text/plain' --header 'Accept: application/json' --header 'Content-Language: en' --header 'Accept-Language: en' -d 'I hate these new features On #ThisPhone after the update.\r\n \
I hate #ThisPhoneCompany products, you%27d have to torture me to get me to use #ThisPhone.\r\n \
The emojis in #ThisPhone are stupid.\r\n \
#ThisPhone is a useless, stupid waste of money.\r\n \
#ThisPhone is the worst phone I%27ve ever had - ever 😠.\r\n \
#ThisPhone another ripoff, lost all respect SHAME.\r\n \
I%27m worried my #ThisPhone is going to overheat like my brother%27s did.\r\n \
#ThisPhoneCompany really let me down... my new phone won%27t even turn on.' 'https://gateway.watsonplatform.net/tone-analyzer/api/v3/tone?version=2017-09-21&sentences=true'
You need to send "query" parameter for querystring. Pleaes check the below codes:
$toneAnalyserResponse = $client->request('POST', 'tone-analyzer/api/v3/tone', [
'auth' => ['{username}', '{password}'],
'headers' => [
'Content-Type' => 'text/plain',
],
'query' => [
'version' => '2017-09-21'
]
]);
Related
unfortunately our project runs on PHP 7.0 and we cannot upgrade it for now. And Twilio's library uses PHP 7.2+ on the version that contains the trusthub API support.
So I'm trying to do the request "Create EndUser of type: customer_profile_business_information" from this doc page using Guzzle instead of their library, and I'm following instructions from the curl example.
Everything worked well except the Attributes field that looks like it's being ignored, it's returning a blank object and of course on their interface it's also not showing.
So in case the link breaks, the curl code example is the following:
ATTRIBUTES=$(cat << EOF
{
"business_identity": "direct_customer",
"business_industry": "EDUCATION",
"business_name": "acme business",
"business_regions_of_operation": "USA_AND_CANADA",
"business_registration_identifier": "DUNS",
"business_registration_number": "123456789",
"business_type": "Partnership",
"social_media_profile_urls": "",
"website_url": "test.com"
}
EOF
)
curl -X POST https://trusthub.twilio.com/v1/EndUsers \
--data-urlencode "Attributes=$ATTRIBUTES" \
--data-urlencode "FriendlyName=friendly name" \
--data-urlencode "Type=customer_profile_business_information" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
And here's the PHP code that I made:
<?php
// $company is a model
$token = base64_encode(\Config::get('twilio.accountSid') . ':' . \Config::get('twilio.authToken'));
$client = new \GuzzleHttp\Client(['base_uri' => 'https://trusthub.twilio.com/v1/', 'headers' => ['Authorization' => "Basic {$token}", 'Content-Type' => 'application/x-www-form-urlencoded']]);
$client->post("EndUsers", [
'form_params' => [
'FriendlyName' => $company->business_name,
'Type' => 'customer_profile_business_information',
'Attributes' => [
'business_name' => $company->business_name,
'business_identity' => 'direct_customer',
'business_type' => $company->business_type,
'business_industry' => $company->industry->twilio_name,
'business_registration_identifier' => 'EIN',
'business_registration_number' => $company->tax_id_number,
'business_regions_of_operation' => $company->region,
'website_url' => $company->website,
'social_media_profile_urls' => '',
]
]
]);
Is there something I'm missing here that it's not saving the Attributes data?
PS: the other fields (FriendlyName and Type) are being successfully saved.
Thank you!
Twilio developer evangelist here.
The Attributes property of Twilio resources tends to be a JSON string, and I think that's the case for this one too. So, rather than passing an array of attributes, you need to json_encode the array first. This should work for you:
<?php
// $company is a model
$token = base64_encode(\Config::get('twilio.accountSid') . ':' . \Config::get('twilio.authToken'));
$client = new \GuzzleHttp\Client(['base_uri' => 'https://trusthub.twilio.com/v1/', 'headers' => ['Authorization' => "Basic {$token}", 'Content-Type' => 'application/x-www-form-urlencoded']]);
$client->post("EndUsers", [
'form_params' => [
'FriendlyName' => $company->business_name,
'Type' => 'customer_profile_business_information',
'Attributes' => json_encode([
'business_name' => $company->business_name,
'business_identity' => 'direct_customer',
'business_type' => $company->business_type,
'business_industry' => $company->industry->twilio_name,
'business_registration_identifier' => 'EIN',
'business_registration_number' => $company->tax_id_number,
'business_regions_of_operation' => $company->region,
'website_url' => $company->website,
'social_media_profile_urls' => '',
])
]
]);
I have this cURL command that I need to convert to PHP using Guzzle 7. I've have been researching this for a few (well, more than a few) days and getting nowhere fast. The cURL command uses the Simpli.fi api to create an organization under the parent org.
curl -i -X POST -H "X-App-Key: xxxx-xx-xx-xx-xxxxxx" -H "X-User-Key: xxxx-xx-xx-xx-xxxxxx" \
-H "Content-Type: application/json" \
-d '{
"organization": {
"name": "My New Organization",
"parent_id": "5786",
"custom_id": "<Put your organization identifier here or omit this optional field>"
}
}' \
"https://app.simpli.fi/api/organizations"
I was able to convert it using this website but it doesn't use Guzzle: https://onlinedevtools.in/curl
Here's what it gave me:
include('vendor/rmccue/requests/library/Requests.php');
Requests::register_autoloader();
$headers = array(
'X-App-Key' => 'xxxx-xx-xx-xx-xxxxxx',
'X-User-Key' => 'xxxx-xx-xx-xx-xxxxxx',
'Content-Type' => 'application/json'
);
$data = '{\n "organization": {\n "name": "My New Organization",\n "parent_id": "5786",\n "custom_id": "<Put your organization identifier here or omit this optional field>"\n }\n }';
$response = Requests::post('https://app.simpli.fi/api/organizations', $headers, $data);
Here's what I've tried so far aside from the converted code above:
public static function createOrganization()
{
self::init();
$client = new Client(['debug' => true]);
$request = $client->request('POST',
self::$baseUrl.'/organizations', [
'multipart' => [
[
'name' => 'data',
'contents' => "{'organization':{'name':'Pete's Pet Pagoda','parent_id':'1052385'}}",
],
],
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
]
]);
dd($response = $request->getStatusCode());
}
I'm getting quite a few different errors however this is the latest:
curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*
Can anyone tell me what I'm doing wrong? Is there something missing?
UPDATE: After further research into this issue and chatting with a developer on the Laracast Slack channel, I've come to learn that this is a bug with the ['debug' => true] option when running on a Windows system and is described on this GITHUB page: https://github.com/guzzle/guzzle/issues/1413
I'm running on a Windows 10 Pro system. I corrected it on my end by changing the debug option to use fopen() like this:
'debug' => fopen('php://stderr', 'w'),
I use PHPStorm. It suggested using the 'wb' to make it binary safe. After changing it, the post requests worked fine.
You need to use body, not multipart. You can also use json.
$request = $client->request('POST',
self::$baseUrl.'/organizations', [
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'body' => [
'{"organization":
[
{
"name":"Pete`s Pet Pagoda",
"parent_id":"1052385"
}
]
}',
],
]);
method 2
You can pass array to the json request option and it will convert it to json when sending the guzzle request. No need to use header as application/json as it applies internally.
$client->request('POST',
self::$baseUrl.'/organizations', [
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'json' => [
"organization" => [
[
"name" => "Pete`s Pet Pagoda"
"parent_id" => "1052385"
]
]
],
]);
I hope this will help you. For further debugging use Middleware::tap(find more help here middleware+json+request)
try{
$client = new Client();
$response = $client->request('POST', self::$baseUrl.'/organizations',
[
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'json' => [
'organization' =>
[
"name" => "some_name_value",
"parent_id" => "id_here",
"custom_id" => "custom id here"
]
]
]);
$_response = json_decode($response->getBody()->getContents(), true);
}
catch(BadResponseException $e){
$response = $e->getResponse();
$errorArray = json_decode($response->getBody()->getContents(), true);
//echo "<pre>";
//print_r($errorArray);
//return some message from errorarray;
}
I've got this CURL that I'm executing on the command line and it successfully creates content in my CMS (Drupal 9).
curl \
--user username:9aqW72MUbFQR4EYh \
--header 'Accept: application/vnd.api+json' \
--header 'Content-type: application/vnd.api+json' \
--request POST http://www.domain.drupal/jsonapi/node/article \
--data-binary #payload.json
and the JSON file as:
{
"data": {
"type": "node--article",
"attributes": {
"title": "My custom title",
"body": {
"value": "Custom value",
"format": "plain_text"
}
}
}
}
Working like a charm and data is being created.
I've been trying to do this in GuzzleHttp but couldn't get it working.
Get is working:
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
$url = 'http://www.domain.drupal';
$content_client = new GuzzleHttp\Client([
'base_uri' => $url,
'timeout' => 20.0,
]);
$res = $content_client->request('GET', '/jsonapi/node/article/71adf560-044c-49e0-9461-af593bad0746');
For POST, I've got probably around 10 versions trial and error but nothing worked.
How can I POST my JSON/Content to Drupal or how can I correctly implement the CURL in Guzzle?
If you want a simple post request to send json body with your headers you can do it simply without using Psr7 Request. Guzzle utilizes PSR-7 as the HTTP message interface.
use GuzzleHttp\Client;
$url = 'http://www.domain.drupal';
$content_client = new Client([
'base_uri' => $url,
'timeout' => 20.0,
]);
$headers = [
'Content-type' => 'application/vnd.api+json',
'Accept' => 'application/vnd.api+json'
];
$payload['data'] = [
'type' => 'node--article',
'attributes' => [
"title" => "My custom title",
"body" => [
"value" => "Custom value",
"format" => "plain_text"
]
]
];
$guzzleResponse = $content_client->post('/jsonapi/node/article/71adf560-044c-49e0-9461-af593bad0746', [
'json' => json_encode($payload),
'headers' => $headers
]);
if ($guzzleResponse->getStatusCode() == 200) {
$response = json_decode($guzzleResponse->getBody());
}
You can write it in try catch block with using RequestException (see this Catching exceptions from Guzzle to know more about it.)
The below cURL works while running shell exec but how do I format this in Guzzle?
shell_exec('curl https://*********************** -H "Authorization: *********************** -X POST -F attributes=\'{"name":"testFile.txt", "parent":{"id":"***********"}}\' -F file=#path/To/File.txt');
I want to convert the shell_exec into Guzzle format like the code below but it produces this error:
Client error: POST https://***********************
resulted in a `405 Method Not Allowed
$response = $client->request('POST', 'https://***********************', [
'debug' => true,
'headers' => $headers,
'form_params' => [
'attributes' => [
'name' => 'testFile.txt',
'parent' => [
'id' => '***********',
]
],
'file' => '#path/To/File.txt',
]
]);
Any idea what I need to change?
As #Zak already said, 405 is the server's response, it's has nothing to do with your code. You should get the same response with cURL.
BTW, to send files you need multipart, not form_params. And Guzzle doesn't support #... notation as command-line cURL does. So see the docs, there is an example.
I have a problem with translating curl to guzzle request.
In docs to create a user i just need to post:
$ curl -XPOST -d '{"username":"test", "password":"super_secret_password"}' -H "Content-Type:application/json" -u "$CLOUDMQTT_USER:$CLOUDMQTT_PASSWORD" https://api.cloudmqtt.com/user
In my project I cannot use curl, so i use guzzle:
$client = new Client();
$res = $client->post('https://api.cloudmqtt.com/user', ['auth' => ['xxx', 'xxx'], 'body' => ["username"=>"user", "password"=>"super_secret_password"]]);
And user is created, I can see new user on the users list on panel, but server is responsing with 500 when creating the user. What am I doing wrong? Maybe my guzzle request is wrong format? I have no idea
https://www.cloudmqtt.com/docs-api.html link to API
This will match up your Guzzle request to the curl request, although I can't say for sure that will solve your 500 error:
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('https://api.cloudmqtt.com/user',
[
'auth' => ['xxx', 'xxx'],
'body' => json_encode(
[
"username"=>"user",
"password"=>"super_secret_password"
]
)
]
);
The differences here include setting the Content-Type header and also encoding the body to json instead of an array (which may not have an effect here?).
EDIT:
It looks like the json parameter will automatically set the header and json_encode the body for you:
$client = new Client();
$response = $client->post('https://api.cloudmqtt.com/user',
[
'auth' => ['xxx', 'xxx'],
'json' =>
[
"username"=>"user",
"password"=>"super_secret_password"
]
]
);
Docs