Polar accesslink API POST users not working - node.js

I'm currently trying to implement Polar accesslink API on an app, but when trying to POST a new user I still get this error:
url: 'https://www.polaraccesslink.com/v3/users/',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
I already have the authorization token, which I know expires every 10min, and I'm using the service through a function that takes the token and the userID as parameters. This is my code:
postUser(memberId: string, token: string) {
const inputBody = { 'member-id': memberId };
const headers = {
'Content-Type': 'application/xml', 'Accept': 'application/json', 'Authorization': 'Bearer ' + token
};
const options = {
method: "POST",
headers: headers,
body: JSON.stringify(inputBody)
}
return new Promise<object>((resolve, reject) => {
fetch('https://www.polaraccesslink.com/v3/users', options)
.then(function(res: any) {
console.log(res)
return res.json();
}).then(function(body: any) {
console.log(body);
});
})
}
I'm implementing it the same way as it is specified in https://www.polar.com/accesslink-api/?javascript--nodejs#users but really don't know what might I be doing wrong. Thanks for helping me!.

I don't have experience with this specific API but i can see you send in the header Content-Type the value application/xml but the request body is JSON formatted.
Try send application/json in that header.
The Content-Type header is used in HTTP to specify the body mime type.
more info in: Content-Type HTTP Header - MDN
I also see this is the exact code in the sample but notice they have 2 sample requests and 2 sample results, one in XML and one in JSON each.

Any ideea why this POST gives 'invalid_Request'?
curl --location --request POST 'https://polarremote.com/v2/oauth2/token?grant_type=authorization_code&code=1f9edc0c5e60a0bab4fd3f1f00571a58' --header 'Authorization: Basic ... DA4OS05ZDc2LTJlNTQwZjFkZTc5ZA==' --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json'

Related

Imgix Purge Post Request fails for unknown reason

I wanna purge an image from the imgix cache, they have a API for that (https://docs.imgix.com/setup/purging-images)
I use axios to make the request from my nodejs backend:
const imgixKey = functions.config().imgix.key;
const headers = {
Authorization: `Bearer ${imgixKey}`,
'Content-Type': 'application/json',
};
const data = JSON.stringify({
type: 'purges',
attributes: {
url: href,
source_id: 'SOsourceId',
},
});
try {
await axios.post('https://api.imgix.com/api/v1/purge', data, { headers });
functions.logger.log('Purged Image successfully' + href);
} catch (e) {
functions.logger.error('Error removing image from cache ' + href + ' -> ' + e);
}
Error removing image from cache {stackoverflowimgpath.png} -> Error: Request failed with status code 400
The problem is other than the status code 400 there is nothing else specified, I checked the image paths and tried different Content-Type headers like in their example but that also did not work.
Since I cannot get any more information out of the response I ask for help here since I do not know how to continue.
Checking imgix documentation, the body of your request should have a data property:
curl -X POST 'https://api.imgix.com/api/v1/purge' \
--header 'Authorization: Bearer <api-key>' \
--header 'Content-Type: application/vnd.api+json' \
--data-raw '{ "data": { "attributes": { "url": "<url-to-purge>" }, "type": "purges" } }'
So, just modify your message to (adding the data property to your json object):
const data = JSON.stringify({
data: {
type: 'purges',
attributes: {
url: href,
source_id: 'SOsourceId',
},
}
});

Linkedin v2 API Image upload get error 400 Bad Request

When I am trying to upload an image using LinkedIn v2 API every time I get a 400 Bad request error.
Reference is taken from Here : Link
Steps I perform in postman:
Step 1:
API: https://api.linkedin.com/v2/assets?action=registerUpload,
Request: POST,
Headers: Authorization: Bearer token, Content-Type: 'application/json', X-Restli-Protocol-Version: '2.0.0'
Request:
{
"registerUploadRequest":{
"owner":"urn:li:organization:724981XXX",
"recipes":[
"urn:li:digitalmediaRecipe:feedshare-image"
],
"serviceRelationships":[
{
"identifier":"urn:li:userGeneratedContent",
"relationshipType":"OWNER"
}
],
"supportedUploadMechanism":[
"SYNCHRONOUS_UPLOAD"
]
}
}
Response: Get uploadUrl
Step2:
End point: uploadURL<from step1's response>,
Request: PUT,
Headers: Authorization: Bearer token, Content-Type: 'image/jpeg', X-Restli-Protocol-Version: '2.0.0', media-type-family:'STILLIMAGE<from step1's response>'
Body: <base_64>
Response: 400 Bad Request
Via curl request working fine.
What I am doing wrong?
Thanks in advance.
'Authorization': Bearer ${ access_token },
'X-Restli-Protocol-Version': '2.0.0',
'Content-Type': 'image/jpg'
body is simply the image file contents or a BLOB
method: POST - worked for me... for some PUT worked

Turning a CURL request into a Node js format with request-promise

I have been trying to convert a working POST CURL request into Node JS format that i can automate. Im reaching a wall with converting it and hoping someone can help.
Here is the curl:
curl -POST https://api-xxxxxxxx/add
-H "Authorization: Bearer xxxxxxx"
-H "Content-Type: multipart/mixed"
-F 'metadata={ "domain_id": 11661, "container_id": 18569512, "name": "TestFile", "size": "1072902", "originalfilename" : "xxx-d6", "mime": "x-html-package",
"attributes":"main_html_file_path=index.html\nduration=10000" }; type=application/json' -F "file=#xxx-d6.x-html-package"
Im using request-promise module to make this request but i might be making a mistake converting it.
let step1Options = {
method: 'POST',
uri: 'https://api-xxx/add',
form: {
metadata: {
domain_id: domainID,
container_id: 1856951,
name: "TestFileNodeJS",
size: "1072902",
originalfilename : "xxx-d6",
mime: "x-html-package",
attributes:"main_html_file_path=index.html\nduration=10000"
},
file: fs.createReadStream("xxx.x-html-package")
},
headers: {
"content-type": "multipart/mixed",
Authorization: "Bearer " + authID
}
};
rp(step1Options)
.then(function (body) {
console.log("success")
console.log(body)
})
.catch(function (err) {
console.log("Error: ", err)
// POST failed...
});
The error im getting:
body:
'{"error":"Unexpected Content-Type header: application/x-www-form-urlencoded. Expecting: multipart/mixed; boundary=<boundary>.","status":"error"}' } }
As far as i know, im changing the Content-Type but still thinks im not. Reading a bit of the documentation of Request-Promise, i dont believe multipart/mixed is a supported? Though i could be wrong.
Does anyone have an idea on how i can get this working or suggest alternatives?

How to POST with multipart/form-data header and FormData using fetch

This is a CURL example which works fine:
curl -X POST \
<url> \
-H 'authorization: Bearer <token>' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F file=#algorithm.jpg \
-F userId=<userId>
I'm trying to reproduce this request using isomorphic-fetch.
I've tried the following code:
const formData = new FormData();
formData.append('file', file);
formData.append('userId', userId);
return fetch(`<url>`, {
method: 'POST',
headers: {
'Content-Length': file.length
'Authorization: Bearer <authorization token>',
'Content-Type': 'multipart/form-data'
},
body: formData
})`
I use fs.readFileSync in order to generate the file passed to FormData.
The previous example returns a 401 HTTP status code (unauthorized) with an error message saying that the userId embedded in the token (sent via header) does not match the userId passed from formData.
So my suspicion is that the FormData that arrives to the REST API is not adequately formed.
The problem may be related with the Content-Length header, but I didn't find a better way to calculate it (if I don't use the Content-Length header I get a 411 HTTP status code Content-Length header missing).
Could be the case that this is failing because of an incorrect value in the Content-Length header?
Any other suggestions on why this is failing or how to better debug it?
If further info is needed to clarify this problem, please just ask.
UPDATE
I've tried the form-data module in order to get the right Content-Length value using the method formData.getLengthSync()
However the problem remains the same (401 error HTTP status code response).
Just remove the Content-Length and Content-Type headers from your code as these headers will be set automatically by the browser.
If you open up your network inspector, run this code snippet, and submit the form you should see that the Content-Length is set correctly:
const foo = document.getElementById('foo')
foo.addEventListener('submit', (e) => {
e.preventDefault()
const formData = new FormData(foo)
formData.append('userId', 123)
fetch('//example.com', {
method: 'POST',
body: formData
})
})
<form id="foo">
<input id="file" type="file" name="file"/><br><br>
<button type="submit">Submit</button>
</form>
I hit my head against a similar wall, specifically using isomorphic-fetch on node to POST a multipart form. The key for me was finding .getHeaders(). Note that NPM description for form-data suggests that it'll "just work" without this, but it doesn't seem to, at least not in node (I think browsers inject header stuff?).
// image is a Buffer containing a PNG image
// auth is the authorization token
const form_data = new FormData();
form_data.append("image", png, {
filename: `image.png`,
contentType: 'application/octet-stream',
mimeType: 'application/octet-stream'
});
const headers = Object.assign({
'Accept': 'application/json',
'Authorization': auth,
}, form_data.getHeaders());
try {
const image_res = await fetch(url, {
method: 'POST',
headers: headers,
body: form_data
});
if (!image_res.ok) {
const out = await image_res.json();
console.dir(out);
return;
}
}
catch (e) {
console.error(`Chart image generation exception: ${e}`);
}

Correspondence between curl command and node's request

How can I execute this cURL shell command curl --data "{\"obj\" : \"1234556\"}" --digest "https://USERNAME:PASSWORD#www.someurl.com/rest-api/v0/objectpost" that correctly returns expected values using node's request package?
I tried with those post options but got no success:
var request = require('request');
var body = {"obj" : "1234556"};
var post_options = {
url: url,
method: 'POST',
auth: {
'user': 'USERNAME',
'pass': 'PASSWORD',
'sendImmediately': false
},
headers: {
'Content-Type': 'text/json',
'Content-Length': JSON.stringify(body).length,
'Accept': "text/json",
'Cache-Control': "no-cache",
'Pragma': "no-cache"
},
timeout: 4500000,
body: JSON.stringify(body)
}
request(post_options, callback);
This way the body is not parsed (got something like missing required parameter: "obj"), and I can't understand if it's a matter of encoding or just passing it in the wrong place (i.e. should not be the body). Any suggestion?
By default, cURL will send a Content-Type: application/x-www-form-urlencoded unless you use -F (which changes it to Content-Type: multipart/form-data) for your fields or explicitly override the header (e.g. -H 'Content-Type: application/json'). However, the data being sent by your cURL example seems to be JSON. So the server will get confused and won't correctly find the data it's expecting.
So the solution is one of two options:
Try application/json as a Content-Type in your code instead of text/json.
Actually use urlencoded formatted data instead of JSON by using the form property. request will take that form object and do all the conversions and setting of headers, etc. for you. For example:
var post_options = {
url: url,
method: 'POST',
auth: {
user: 'USERNAME',
pass: 'PASSWORD',
sendImmediately: false
},
timeout: 4500000,
form: body
};

Resources