Microsoft Graph API PUT OneDrive/SharePoint - sharepoint

Trying to post a file to a subfolder of the Shared Documents folder. I thought I had the correct syntax down, but I keep getting StatusCode 400 Bad Request.
https://graph.microsoft.com/v1.0/sites/xxxxxx.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/drives/b!tDVUScNgt0mPbh0mKhIK5WefrQ-oNQtMiS4RMIQFjAqJk9Tt237bQYC9yEkyNOr6/items/01JDP7KXJ7ZSCYHUJC7BFJW2X6BTR4Z4JH:/filename.xlsx:/content
where "filename" is the actual filename.
I know a GET to the following lists the subfolder:
https://graph.microsoft.com/v1.0/sites/xxxxxx.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/drives/b!tDVUScNgt0mPbh0mKhIK5WefrQ-oNQtMiS4RMIQFjAqJk9Tt237bQYC9yEkyNOr6/items/01JDP7KXJ7ZSCYHUJC7BFJW2X6BTR4Z4JH
Request is going out as:
{Method: PUT, RequestUri: 'https://graph.microsoft.com/v1.0/sites/xxxxxx.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/drives/b!tDVUScNgt0mPbh0mKhIK5WefrQ-oNQtMiS4RMIQFjAqJk9Tt237bQYC9yEkyNOr6/items/01JDP7KXJ7ZSCYHUJC7BFJW2X6BTR4Z4JH:/', Version: 2.0, Content: <null>, Headers:
{
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub...BXS_cSg1CcZHj5Q
}}
Seems like it is dropping part of the request to me.

First, https://graph.microsoft.com/v1.0/sites/xxx.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/drives and https://graph.microsoft.com/v1.0/sites/xxx.sharepoint.com/drives will return the same results, we prefer the second one.
I have never sucessful run the following API:
/drives/{drive-id}/items/{parent-id}:/{filename}:/content
But based on my test, the following API works well:
/v1.0/me/drive/root:/Test/Test1.txt:/content
or
/v1.0/me/drives/driveid/root:/Test/Test1.txt:/content

Related

My Request Body is so long. How do you handle it while doing API testing via Cypress

My request body for an endpoint is so long:
1st question: I read that we can use some request.body.js file for storing our request body and then call it where ever we need it. But unfortunately, I could not find any sample framework/tutorial to learn it.
2nd question: in my project the properties of the request body (especially names of properties) are not exactly matching with the response body that is gaven in the Swagger document. What can be the reason? What would be your approach?
I would appreciate it if you could help me to ridd off the question in the best possible way. Thank you!
It's quite straight forward, take a look at this login example:
cy.fixture('users.json').then((userdata) => {
cy.request({
method: 'POST',
url: <auth_url>,
form: true,
body: userdata
});
});
You can export this as cypress function and then have it available in all your test spec files.
users.json file in fixtures folder looks like this:
{
"username": "...",
"password": "..."
}
Hope that answers the first question at least.

How to share files in dropbox api using node.js

I want to share uploaded files in dropbox with another member.
add_member={
method: "POST",
url:'https://api.dropboxapi.com/2/sharing/add_file_member',
headers:{
"content-Type":"application/json",
"Authorization": "Bearer " + access_token,
"Data":"{\"file\": \"id:3kmLmQFnf1AAAAAAAAAAAw\",\"members\": [{\".tag\": \"email\",\"email\": \"jyotijagtap2209#gmail.com\"}],\"custom_message\": \"This is a custom message about ACME.doc\",\"quiet\": false,\"access_level\": \"viewer\",\"add_message_as_comment\": false}"
},
body:content
}
request(add_member,function(err,res,body){
console.log("link shared", body);
})
This is my code. I have also read documentation for Dropbox API but I can't get what is id given to this file and I didn't get any error. What I am missing?
The file parameter you supply to /2/sharing/add_file_member should be the id for the file for which you want to add a file member.
You can get the id for a file from the Metadata for the file, such as is returned by /2/files/get_metadata or /2/files/list_folder[/continue], for instance.
Also, note that /2/sharing/add_file_member uses the RPC request/response style, so your parameters should be sent as JSON in the request body, not a header.
In any case, make sure you check the resulting response status code and body to see if the call succeeded or failed, and to retrieve any returned result or error information.

Azure Logic App: how to make a x-www-form-encoded?

I'm trying to make a request with Content-Type x-www-form-urlencoded that works perfectly in postman but does not work in Azure Logic App I receive a Bad Request response for missing parameters, like I'd not send enything.
I'm using the Http action.
The body value is param1=value1&param2=value2, but I tried other formats.
HTTP Method: POST
URI : https://xxx/oauth2/token
In Headers section, add the below content-type:
Content-Type: application/x-www-form-urlencoded
And in the Body, add:
grant_type=xxx&client_id=xxx&resource=xxx&client_secret=xxx
Try out the below solution . Its working for me .
concat(
'grant_type=',encodeUriComponent('authorization_code'),
'&client_id=',encodeUriComponent('xxx'),
'&client_secret=',encodeUriComponent('xxx'),
'&redirect_uri=',encodeUriComponent('xxx'),
'&scope=',encodeUriComponent('xxx'),
'&code=',encodeUriComponent(triggerOutputs()['relativePathParameters']['code'])).
Here code is dynamic parameter coming from the previous flow's query parameter.
NOTE : **Do not forget to specify in header as Content-Type ->>>> application/x-www-form-urlencoded**
Answering this one, as I needed to make a call like this myself, today.
As Assaf mentions above, the request indeed has to be urlEncoded and a lot of times you want to compose the actual message payload.
Also, make sure to add the Content-Type header in the HTTP action with value application/x-www-form-urlencoded
therefore, you can use the following code to combine variables that get urlEncoded:
concat('token=', **encodeUriComponent**(body('ApplicationToken')?['value']),'&user=', **encodeUriComponent**(body('UserToken')?['value']),'&title=Stock+Order+Status+Changed&message=to+do')
When using the concat function (in composing), the curly braces are not needed.
First of all the body needs to be:
{ param1=value1&param2=value2 }
(i.e. surround with {})
That said, value1 and value2 should be url encoded. If they are a simple string (e..g a_b) then this would be find as is but if it is for exmaple https://a.b it should be converted to https%3A%2F%2Fa.b
The easiest way I found to do this is to use https://www.urlencoder.org/ to convert it. convert each param separately and put the converted value instead of the original one.
Here is the screenshot from the solution that works for me, I hope it will be helpful. This is example with Microsoft Graph API but will work with any other scenario:

Podio file attached to item cannot be downloaded

I have an issue trying to download files attached to Podio items:
podio.request('get', '/file/{file_id}/raw').then(console.log);
The above program displays:
{}
This is a JSON stringified empty object (instead of raw file content).
Details:
The above file can be accessed with its URL when logged in
The above code is run after proper authentication
It actually works when using a file_id from an image field of the item, but not from a file attachment (pdf files in my case).
When using API endpoint /item/app/{app_id}/filter to get a list of items, the property file_count is set, but not files. I have to request /item/{item_id} individually to get the files property included in the response, not sure why.
Question: Do you know what is the issue, and how I can download raw attached files?
EDIT: aditionnal info
If I request a single file metadata using the folowing command:
podio.request('get', '/file/1234').then(console.log);
I get a file JSON object which includes many fields, but not the file content :
{
...
link: 'https://files.podio.com/1234',
file_id: 1234,
...
}
As stated in my comment to #stengaard, if I try to request the API for the above link, here is the response :
{ [PodioNotFoundError: [object Object]]
message:
{ error_parameters: {},
error_detail: null,
error_propagate: false,
request:
{ url: 'http://api.podio.com/1234',
query_string: '',
method: 'GET' },
error_description: 'No matching operation could be found. The path \'/1234\' was not found..',
error: 'not_found' },
status: 404,
url: 'https://api.podio.com:443/1234',
name: 'PodioNotFoundError' }
To use the GET /file/{file_id}/raw endpoint you need an API key with elevated trust levels.
Instead use GET /file/{file_id} endpoint. That contains a link attribute (a URL) you should follow to get the file content.
The link attribute will look like: https://files.podio.com/{file_id}. To fetch the file do https://files.podio.com/{file_id}?oauth_token={oauth_token}. Where the OAuth token is the same as the one used to GET /file/{file_id}. If you know the file ID (e.g. from a GET /item/{item_id} you can skip the GET /file/{file_id} and contact files.podio.com directly. (Note: You can also set the Authorization: OAuth2 {oauth_token} header in your HTTP request if you don't like passing the auth token in a URL paramter.)
For an example on how to use it see https://github.com/podio/podio-js/blob/master/lib/general.js#L11
Typically in the JS client, if you use podio as your Podio API object, the OAuth token would be located there:
podio.authObject.accessToken
So to get the raw content of the file in nodejs:
var url = 'https://files.podio.com/'+file_id+'?oauth_token='+podio.authObject.accessToken;
request(url, function (err, fileContent) {
// use fileContent here, write to a file, etc...
});
It seems your request has an error.
please try the below method and get raw file content from its response.
podio.request('get', '/file/{file_id}').then(console.log);
FYI, we couldn't get the files by filtering the items. we need to request /item/{item_id} individually to get the files property as you said.

Google Translate API always returning "Required parameter: q" as error

I've been using Google Translate API for a while now, without any problems.
I recently pushed my app to my new server and even if it has been working perfectly on my local server, the same source code always gives me the "Required parameter: q" as error message.
I'm using NodeJS + ExpressJS + Request to send this request. Here's my test case:
var request = require('request');
request.post({
url: "https://www.googleapis.com/language/translate/v2",
headers: {"X-HTTP-Method-Override": "GET"},
form: {
key: /* My Google API server key */,
target: "en",
q: ["Mon premier essai", "Mon second essai"]
}
}, function(error, response, data) {
if (!error && response.statusCode == 200) {
console.log("everything works fine");
} else {
console.log("something went wrong")
}
});
Running on my local machine gives me "everything works fine", and running it on my server gives me "something went wrong". Digging more into it, I get the error message mentioned above.
As you can see, I'm trying to translate in one request two sentences. It's just a test case, but I really need to use this through POST request instead of doing two GET request.
I have no idea what this is happening, and I double checked my Google settings and I can't find something wrong there.
Also, I'm having no problem using Google Places APi with this same api key on my server.
I'm stuck. Anyone has any idea what's wrong here?
Well I finally found what was wrong: the new version of RequestJS doesn't work as the old one and my server was running 2.16 when my local machine was running 2.14.
The difference is the way the array is sent. I debugged and the old version was sending
key=my_api_key&target=en&q=Mon%20premier%20essai&q=Mon%20second%20essai
When the new version is sending
key=my_api_key&target=en&q[0]=Mon%20premier%20essai&q[1]=Mon%20second%20essai
So I just added 2.14.x instead of 2.x in my package.json file for now, hopefully it will get fixed soon — or maybe it's not a bug? I don't know.
This answer is a little late but to help people out there with this problem. The problem comes from the way the querystring module converts array parameters:
https://github.com/visionmedia/node-querystring
Its function qs.stringify converts fieldnames (q in the given example) that have an array value to the format:
q[0]=..q[1]=...
This is not a bug but an intended functionality. To overcome this problem without reverting to an old version of the request module you need to manually create your post by using the body option instead of the form option. Also you will need to manually add the content-type header with this method:
var request = require('request');
request.request({
url: "https://www.googleapis.com/language/translate/v2",
headers: {
"X-HTTP-Method-Override": "GET",
'content-type':'application/x-www-form-urlencoded; charset=utf-8'
},
body:'key=xxxx&target=en&q=q=Mon%20premier%20essai&q=Mon%20second%20essai'
}, function(error, response, data) {
if (!error && response.statusCode == 200) {
console.log("everything works fine");
} else {
console.log("something went wrong")
}
});
Obviously this is not as clean but you can easily create a utility function that creates the body string from the object the way you want it to.
things that pop into my head:
jquery file version on server and local PC are not the same
file encoding issues (UTF8 on PC ascii on server?)
have you tried testing it with chrome with Developer Tools open, then check "Network Tab" and verify exactly what is being sent to Google.
For me at least, when it works on one machine and not the other, it is usually due to the first 2 options.
Good Luck!

Resources