OneDrive REST API error 400 when creating folder - rest

I have a problem when trying to create a folder in my OneDrive using the REST API. I'm using following documentation page https://dev.onedrive.com/items/create.htm. I have successfully authenticated and the token is working ok on other endpoints.
I spent now over a day trying every possible URI/method combination on this one but with no success. All other endpoints (directory listing etc.) are OK, just this one is driving me crazy.
If anyone could point me to the error in my approach, any help would be appreciated.
The code below returns error 400 with following message:
{"error":{"code":"invalidRequest","message":"The request is malformed or incorrect."}}
I'm using GuzzlePhp library for the request handling. My code (simplified):
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'form_params' => [
"name" => "NewFolder",
"folder" => (object)[],
"#name.conflictBehavior" => "fail"
]
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);

The OneDrive API doesn't support form post semantics - the parameters are expected in the body as a JSON encoded blob. I haven't used Guzzle, but something like this should work:
$parentId = '01WZZ7ZY2LNHB75JADQJD3GGUQFSCRRZTQ'; //id to root
$method = "POST";
//none of these does the trick (to be clear, I use only one at the time)
$url = '/_api/v2.0/drive/items/'.$parentId.'/NewFolder'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //put
$url = '/_api/v2.0/drive/items/'.$parentId.'/children'; //post
$url = '/_api/v2.0/drive/root:/NewFolder'; //post
$options = [
'headers' => [
'Authorization' => $token,
'Content-Type' => 'application/json',
'Content-Length'=> 0,
]
'body' =>
'{
"name": "NewFolder",
"folder": { },
"#name.conflictBehavior": "fail"
}'
];
//Guzzle library sends the code as specified
$res = $this->client->request($method, $url, $options);

Related

guzzle 6 post does not work

I am trying to submit a post with JSON content. I always get this message back:
"Client
error: POST
https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001
resulted in a 400 Bad Request response: {"Message":"No data was
submitted."}"
(All keys and license number are sandbox. I changed keys slightly so auth wont work. )
here is my code
public function metrc()
{
$client = new Client();
$url = 'https://sandbox-api-ca.metrc.com//strains/v1/create?licenseNumber=CML17-0000001';
$request = $client->post($url, [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['name' => "Spring Hill Kush"],
'auth' => ['kH-qsC1oJPzQnyWMrXjw0EQh812jHOX52ALfUIm-dyE3Wy0h', 'fusVbe4Yv6W1DGNuxKNhByXU6RO6jSUPcbRCoRDD98VNXc4D'],
]);
}
Your code is correct, it should works as expected. Seems that the issue is on the server side. Maybe the format of the POST request is not correct?
BTW, 'headers' => ['Content-Type' => 'application/json'] is unnecessary, Guzzle sets the header by itself automatically when you use json option.

Guzzle getBody() after request return posted body

I'm using Guzzle 6.3. I'm trying to post a data with a header.
This is my code:
$headers = [
'content-type' => 'application/json',
'Accept' => 'application/json'
];
$request = new Psr7\Request('post', 'product', $headers, json_encode($data));
$res = $this->http->send($request);
$resData = json_decode($res->getBody(), true);
The response body ($resData) is always equal to the posted one ($data).
Thank you.
Try
$resData = json_decode($res->getBody()->getContents(), true);
Otherwise (if it doesn't help) check what your API endpoint returns.

Magento 2 Rest API Order edit

I'm trying to figure out how to edit an order after I requested it.
I made a custom attribute whether an order is exported or not.
I first get all orders with status not exported and after I exported them, I want to change the custom attribute to exported.
What is the REST request to edit/update an order? I keep getting error messages like:
{"message":"%fieldName is a required field.","parameters":
{"fieldName":"entity"}
This is my code:
$json = array(
"entity_id" => $id,
"extension_attributes" => array(
"custom_export_attribute" => "exported",
)
);
$webapi = new ApiClient('https://dev.local.nl', self::$username, self::$password);
$response = $webapi->getClient()->request('PUT', '/rest/V1/orders/create', [
'headers' => [
'Authorization' => "Bearer " . $webapi->getToken(),
'Content-Type' => "application/json"
],
'body' => json_encode($json)
]);
return json_decode($response->getBody(), true);
I also tried:
$webapi->getClient()->request('PUT', '/rest/V1/orders/'.$id,
To edit / update order details, the Magento 2 /V1/orders accepts POST request method. As per Magento 2 Dev Doc, it accepts the request body in below format (You can find whole JSON request in documentation page):
{
"entity": {
"entity_id": 0,
"extension_attributes": {
}
}
}
So, you just need to update the $json variable as:
$json = [
"entity"=> [
"entity_id" => $id,
"extension_attributes" => [
"custom_export_attribute" => "exported"
]
]
]
And than invoke with POST request method instead of PUT. In my suggestion prefer to use Create API for new order creation.

need to set headers on guzzle request

I need to add the type of headers to the guzzle request below, but cannot figure out how to put it in without getting an error
This is what I want to add :
$command->set('command.headers', array('content-type' => 'application/x-www-form-urlencoded
to this code below:
<?php
$url = "https://jsonplaceholder.typicode.com/posts";
$client = \Drupal::httpClient();
$post_data = array('color' => 'red');
$response = $client->request('POST', $url, [
'form_params' => $post_data,
'verify' => false
]);
$body = $response->getBody();
dsm($body);
?>
When I needed use the Guzzle at D8 to make a POST I passed the Content-Type like this:
$url = "https://jsonplaceholder.typicode.com/posts";
$client = \Drupal::httpClient();
$post_data = array('color' => 'red');
$response = $client->request('POST', $url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => rawData($post_data),
]);
$body = $response->getBody()->getContents();
$status = $response->getStatusCode();
A good idea is use the D8 Dependency Injection to pass the HTTP_CLIENT.

JWT: Why am I always getting token_not_provided?

I am sending a PUT request to an API endpoint I have created. Using jwt, I am able to successfully register and get a token back.
Using Postman, my request(s) work perfectly.
I am using Guzzle within my application to send the PUT request. This is what it looks like:
$client = new \Guzzle\Http\Client('http://foo.mysite.dev/api/');
$uri = 'user/123';
$post_data = array(
'token' => eyJ0eXAiOiJKV1QiLCJhbGc..., // whole token
'name' => 'Name',
'email' => name#email.com,
'suspended' => 1,
);
$data = json_encode($post_data);
$request = $client->put($uri, array(
'content-type' => 'application/json'
));
$request->setBody($data);
$response = $request->send();
$json = $response->json();
} catch (\Exception $e) {
error_log('Error: Could not update user:');
error_log($e->getResponse()->getBody());
}
When I log the $data variable to see what it looks like, this is what is returned.
error_log(print_r($data, true));
{"token":"eyJ0eXAiOiJKV1QiL...","name":"Name","email":"name#email.com","suspended":1}
Error: Could not suspend user:
{"error":"token_not_provided"}
It seems like all data is getting populated correctly, I am not sure why the system is not finding the token. Running the "same" query through Postman (as a PUT) along with the same params works great.
Any suggestions are greatly appreciated!
The token should be set in the authorization header, not as a post data parameter
$request->addHeader('Authorization', 'Basic eyJ0eXAiOiJKV1QiL...');