Shopify API - create webhook (batch request) - php

I've managed to go through creating webhook using Shopify API, but I can create only one webhook per request. I've already tried to customize the request so it could possibly create a few webhooks at once, but it doesn't seem to work.
I'm using GuzzleHttp\Client for my requests and this is what my working request look like:
$client = new Client();
$response = $client->request(
'POST',
"https://{$store}/admin/webhooks.json",
[
'headers' => [
'X-Shopify-Access-Token' => $access_token,
'X-Shopify-Shop-Domain' => $store
],
'form_params' => [
'webhook' => [
"topic" => "orders/create",
"address" => $appAddress,
"format" => "json"
],
]
]);
But when I try something like this:
$client = new Client();
$response = $client->request(
'POST',
"https://{$store}/admin/webhooks.json",
[
'headers' => [
'X-Shopify-Access-Token' => $access_token,
'X-Shopify-Shop-Domain' => $store
],
'form_params' => [
'webhook' => [
[
"topic" => "orders/create",
"address" => $appAddress,
"format" => "json"
],
[
"topic" => "orders/delete",
"address" => $appAddress,
"format" => "json"
]
]
]
]);
Im getting this:
POST https://smshopify.myshopify.com/admin/webhooks.json resulted in
a 422 Unprocessable Entity response: {"errors":{"topic":["can't be blank","Invalid topic specified. Topics allowed: app/uninstalled,
carts/create, carts/u (truncated...)
Is there a way to create couple webhooks in one request, I couldn't find a word about it in Shopify documentation, and my attempts to modify request body are not very successful. What I've managed to do is just foreach topics array and to the single request for every webhook.

No, there is no way to create a batch of webhooks in one request. This is true for most Shopify resources - e.g. products must also be created one-by-one.

Related

Trying to use Laravel HTTP to upload a file to a 3rd party

I have the following Postman request for testing a third party API;
What I am trying to do is convert this into code using Laravel's HTTP class, the code i currently have is;
public function uploadToThridParty()
{
$uploadContents = [
'id' => 'this-is-my-id',
'fileUpload' => true,
'frontfile' => Storage::get('somefrontfile.jpg'),
'sideview' => Storage::get('itsasideview.png'),
];
$request = Http::withHeaders(
[
'Accept' => 'application/json',
]
);
$response = $request
->asForm()
->post(
'https://urltoupload.com/upload', $uploadContents
)
}
But every time I run this, the 3rd party API comes back with Invalid ID, even though if i use Postman with the same ID it works fine.
I cant seem to figure out where i am going wrong with my code;
As #Cbroe mention about attach file before sending post request you can make this like this example:
public function uploadToThridParty()
{
$uploadContents = [
'id' => 'this-is-my-id',
'fileUpload' => true
];
$request = Http::withHeaders(
[
'Accept' => 'application/json',
]
);
$response = $request
->attach(
'frontfile', file_get_contents(storage_path('somefrontfile.jpg')), 'somefrontfile.jpg'
)
->attach(
'sideview', file_get_contents(storage_path('itsasideview.png')), 'itsasideview.jpg'
)
->post(
'https://urltoupload.com/upload', $uploadContents
)
}
Also i think you need remove asForm method because it's override your header accept type to application/x-www-form-urlencoded that is way your exception is Invalid ID
Some third party API would require you to have the request with content type as multipart/form data
you can double check all the headers being pass on your postman request HEADERS tab and view on Hidden headers.
If you indeed need your request to be in multipart/form-data, You can use the multipart options of guzzle.
Although this doesnt seem to be on Laravel HTTP-Client docs, you can simply pass a asMultipart() method in your HTTP request
just check the /vendor/laravel/framework/src/Illuminate/Support/Facades/Http.php for full reference of HTTP client.
You can have your request like this.
public function uploadToThridParty() {
$uploadContents = [
[
'name' => 'id',
'contents' => 'this-is-my-id'
],
[
'name' => 'fileUpload',
'contents' => true
],
[
'name' => 'frontfile',
'contents' => fopen( Storage::path( 'somefrontfile.jpg' ), 'r')
],
[
'name' => 'sideview',
'contents' => fopen( Storage::path( 'itsasideview.jpg' ), 'r')
],
];
$request = Http::withHeaders(['Accept' => 'application/json']);
$response = $request->asMultipart()->post('https://urltoupload.com/upload', $uploadContents );
}

Guzzle: Sending POST with Nested JSON to an API

I am trying to hit a POST API Endpoint with Guzzle in PHP (Wordpress CLI) to calculate shipping cost. The route expects a RAW JSON data in the following format:
{
"startCountryCode": "CH"
"endCountryCode": "US",
"products": {
"quantity": 1,
"vid": x //Variable ID
}
}
Link to the API I am consuming: https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate
$body = [
"endCountryCode" => "US",
"startCountryCode" => "CN",
"products" => [
'vid' => $vid,
'quantity' => 1
],
];
$request = $this->client->request(
'POST', 'https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate',
[
'headers' => [
'CJ-Access-Token' => $this->auth_via_cj(), // unnecessary, no auth required. Ignore this header
],
'body' => json_encode( $body )
],
);
I've also tried using 'json' => $body instead of the 'body' parameter.
I am getting 400 Bad Request error.
Any ideas?
Try to give body like this.
"json" => json_encode($body)
I spent so many hours on this to just realise that products is actually expecting array of objects. I've been sending just a one-dimensional array and that was causing the 'Bad Request' error.
In order to fix this, just encapsulate 'vid' and 'quantity' into an array and voila!
You don't need to convert data in json format, Guzzle take care of that.
Also you can use post() method of Guzzle library to achieve same result of request. Here is exaple...
$client = new Client();
$params['headers'] = ['Content-Type' => 'application/json'];
$params['json'] = array("endCountryCode" => "US", "startCountryCode" => "CN", "products" => array("vid" => $vid, "quantity" => 1));
$response = $client->post('https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate', $params);

How to fix the errors in quickbooks API, GuzzleHttlp saying Request has invalid or Unsupported Property

I was working on the Quickbooks API for one of my projects. I'm getting the following error:
GuzzleHttp\Exception\ClientException Client error: POST https://sandbox-quickbooks.api.intuit.com//*Private Info */ resulted in a 400 Bad Request response: {"Fault":{"Error":[{"Message":"Request has invalid or unsupported property","Detail":"Property Name:Unrecognized field \ (truncated...)
The Code:
I have no idea what it is saying to me to fix it. Can anyone help me with this?
Please find the updated code
if(!$buyer->details->quickbooks_id){
$customer = $http->post(
// Sandbox API hidden for security reason
[
'headers' => [
'Accept'=> 'application/json',
'Content-type'=> 'application/json',
'Authorization'=> 'Bearer '.$oauth['access_token']
],
'body' => json_encode(
[
'PrimaryEmailAddr' => [
'Address' => $buyer->email
],
'DisplayName' => $buyer->first_name.' '.$buyer->last_name.' - '.$buyer->details->business_name,
'PrimaryPhone'=>[
'FreeFormNumber'=> $buyer->phone
],
'CompanyName'=>$buyer->details->business_name,
'GivenName'=>$buyer->first_name,
'FamilyName'=>$buyer->last_name,
'BillAddr'=> [
"CountrySubDivisionCode" => $buyer->details->state,
"City" => $buyer->details->city,
"PostalCode" => $buyer->details->zip,
"Line1" => $buyer->details->address,
"Country" => $buyer->details->country
]
])
]
);
$customer = json_decode((string)$customer->getBody(), true);
$buyer->details->quickbooks_id = $customer['Customer']['Id'];
$buyer->details->save();
}
dd($buyer, $buyer->details, $buyer->details->quickbooks_id);
Probably the issue is with the request body. I had the same issue with the data i pass.

How can I use Guzzle to send a PUT request?

Does anybody know the correct way to PUT using Guzzle? my code is not working
but my post methods are working
$enrolment = $client->request('PUT', $url,[
'form_params' => [
'contactID' =>12345,
'type' =>'w'
],
'headers' => [
'apitoken' => $api_token,
'wstoken' => $ws_token
]
]);
resulted in a 500 Internal Server Error response:↵{"DATA":"","ERROR":true,"MESSAGES":"key [TYPE] doesn't exist","CODE":"0","DETAILS":""}
The PUT request does't accept form_params type as request option, so it may ignore the setting.
From Docs:
form_params
Used to send an application/x-www-form-urlencoded
POST request.
Maybe you can try using json for PUT request.
In the json part of Docs, it uses PUT as well.
$enrolment = $client->request('PUT', $url,[
'json' => [
'contactID' =>12345,
'type' =>'w'
],
'headers' => [
'apitoken' => $api_token,
'wstoken' => $ws_token
]
]);

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',
],
]);

Categories