Convert Paypal cURL command to Axios request - node.js

Following Paypal cURL command works as it supposed to be but unfortunately I couldn't convert to axios code to work same. Paypal Documentation doesn't have form data example but it allows that if you need to optional message_document file.
curl --request POST \
--url https://api-m.sandbox.paypal.com/v1/customer/disputes/12345/send-message` \
--header 'authorization: Bearer --token--' \
--header 'content-type: multipart/form-data' \
-F "input={\"message\":\"sample message\"};type=application/json" \
-F "message_document=#sample.pdf"
I tried that Node.js code even without sending file but not successful:
const FormData = require('form-data');
const form = new FormData();
form.append('input', JSON.stringify({ message: 'sample message' }), { contentType: 'application/json' });
const result = await axios({
url: 'https://api-m.sandbox.paypal.com/v1/customer/disputes/12345/send-message',
method: 'post',
data: form,
headers: {
'Content-Type': 'multipart/form-data',
Authorization: 'Bearer --token--'
}
}).catch(err => {
throw new Error(err);
});
I can't see that where is the problem. Please enlighten me. Thanks in advance.

I wasn't expecting but it is solved with missing boundary information. These can be used:
const result = await axios({
url: 'https://api-m.sandbox.paypal.com/v1/customer/disputes/12345/send-message',
method: 'post',
data: form,
headers: {
'Content-Type': `multipart/form-data; boundary=${form._boundary}`,
Authorization: 'Bearer --token--'
}
})
or
const result = await axios({
url: 'https://api-m.sandbox.paypal.com/v1/customer/disputes/12345/send-message',
method: 'post',
data: form,
headers: {
Authorization: 'Bearer --token--',
...form.getHeaders()
}
})

Related

Converting Curl to Nodejs Axios - Obtaining an Access Token

I am currently using curl in order to obtain an access token so I can consume an api with said token. The curl command I use is as follows:
curl --user <client_id>:<client_secret> https://api.ed-fi.org/v3/api/oauth/token --data 'grant_type=client_credentials'
It works and all...but instead of curling I want to utilize the axios library to get this access token instead.
Here's what I have but it doesn't work.
const buff = new Buffer.from('<client_id>:<client_secret>';
const base64data = buff.toString('base64');
axios({
method: 'POST',
url: 'https://api.ed-fi.org/v3/api/oauth/token',
headers: {
Authorization: `Basic ${base64data}`
},
data: { 'grant_type': 'client_credentials' }
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
I can't figure out what I'm missing or doing wrong?
You should change Content-Type (default for axios is JSON) and pass body just like you did in case of curl:
axios({
method: 'POST',
url: 'https://api.ed-fi.org/v3/api/oauth/token',
headers: {
Authorization: `Basic ${base64data}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'grant_type=client_credentials'
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});

POST using multipart/form-data in NodeJS

I need to essentially POST a local image to Cisco Webex room from my NodeJS service. For local files, you need to do a multipart/form-data request instead of JSON as mentioned in the documentation.
The CURL looks like
curl --request POST \
--header "Authorization: Bearer ACCESS_TOKEN" \
--form "files=#/home/desktop/example.png;type=image/png" \
--form "roomId=Y2lzY2....." \
--form "text=example attached" \
https://api.ciscospark.com/v1/messages
But I am not sure how to convert it to nodeJS request format. I tried to use CURL to Node request converter here but doesn't seem like it is handling the multipart/form-data type. Please suggest.
EDIT: after doing some research, I came up with the below code
var request = require('request');
var fs = require('fs');
var params = { roomId: ROOMID,
text: "hello....",
files: {
value: fs.createReadStream(PATH_WO_FILENAME),
options: {
filename: 'image.jpg',
contentType: 'jpg'
}
}
};
var headersWebex = {
'Authorization': 'Bearer MY_BOT_ACCESS_TOKEN',
'Content-Type': 'multipart/form-data' }
request.post({
headers: headersWebex,
url: 'https://api.ciscospark.com/v1/messages',
method: 'POST',
body: params
}, function(error, response, body){
console.log(body);
});
But it is throwing error
undefined
_http_outgoing.js:642
throw new TypeError('First argument must be a string or Buffer');
Ok so here is how I made it work. I essentially needed to look deeper into the docs that #Evan mentioned
var request = require('request');
var fs = require('fs');
var roomID = 'MY_ROOM_ID'
var params = {
roomId: roomID,
text: "hello....",
files: {
value: fs.createReadStream('./image.jpg'),
options: {
filename: 'image.jpg',
contentType: 'image/jpg'
}
}
};
var headersWebex = {
'Authorization': 'Bearer MY_BOT_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
request.post({
headers: headersWebex,
url: 'https://api.ciscospark.com/v1/messages',
method: 'POST',
formData: params
}, function(error, response, body){
if (error)
console.log(error)
console.log(body);
});

How to use bearer token for authorization for POST method in sync-request?

How can we use bearer token with POST method using npm sync-request? The sync-request resource page has the way to use authorization in GET request but not in POST request.
*******GET Request*******
var request = require('sync-request');
var res = request('GET', 'https://example.com', {
'headers': {
'user-agent': 'example-user-agent'
}
});
****POST Request*****
var request = require('sync-request');
var res = request('POST', 'https://example.com/create-user', {
json: { username: 'Name' }
});
Not sure why you would want to use sync-request which can cause timing issues but this should work with either sync-request or request
// *******GET Request*******
var request = require('sync-request');
var res = request('GET', 'https://example.com', {
'headers': {
'user-agent': 'example-user-agent',
'authorization', 'Bearer ' + authId
}
});
// ****POST Request*****
var request = require('sync-request');
var res = request('POST', 'https://example.com/create-user', {
'headers': {
'authorization', 'Bearer ' + authId
},
json: { username: 'Name' }
});
authId needs to be whatever your bearer token spoils be for your app.
I would suggest use of axis and example below:-
GET
import axios from "axios";
axios({
method: 'get',
url: url,
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
console.log(response);
}).catch((err) => {
console.log(err)
));
POST
axios({
method: 'post',
url: url,
data: JSON.stringify({orders}),
headers: {
'Content-Type': 'application/json',
'Authorization': userObj.token
}
}).then(function (response) {
console.log(response)
});
Where ubserObj.token -
Bearer Token ex: Bearer ASDF#!##!ADFASDF!##!##
This will be on the server side settings.

Nodejs - Rest api call with option --data from a file

I am making rest api calls from a nodejs application.
My curl calls looks like this:
curl -X PUT -iv -H "Authorization: bearer <token>" -H "Content-Type: application/json" -H "Accept: application/json" -H "X-Spark-Service-Instance: <spark-instance>" --data "#pipeline.json" -k https://<url>
I want to have a similar call in Nodejs. I am unable to understand how to have the data sent which is in a json file which in curl call was --data "#pipeline.json".
My Nodejs code looks like this:
var token = req.body.mlToken;
var urlToHit = req.body.url;
var SPARKINSTANCE = req.body.sparkInstance;
var b = "bearer ";
var auth = b.concat(token);
var headers = {
'Content-Type': 'application/json',
'Authorization': auth,
'Accept': 'application/json',
'X-Spark-Service-Instance': SPARKINSTANCE
}
var options= {
url: urlToHit,
method: 'PUT',
headers: headers
}
console.log(urlToHit);
request(options, callback);
function callback(error, response, body) {...}
You can either use the request library to pipe the request as so:
var fs = require('fs');
var options= {
url: urlToHit,
method: 'PUT',
headers: headers
}
fs.createReadStream('./pipeline.json')
.pipe(request.put(options, callback))
Or, using plain Node.js, read the file in to memory asynchronously and the once loaded, make a put request like this:
var fs = require('fs');
// Will need this for determining 'Content-Length' later
var Buffer = require('buffer').Buffer
var headers = {
'Content-Type': 'application/json',
'Authorization': auth,
'Accept': 'application/json',
'X-Spark-Service-Instance': SPARKINSTANCE
}
var options= {
host: urlToHit,
method: 'PUT',
headers: headers
}
// After readFile has read the whole file into memory, send request
fs.readFile('./pipeline.json', (err, data) => {
if (err) throw err;
sendRequest(options, data, callback);
});
function sendRequest (options, postData, callback) {
var req = http.request(options, callback);
// Set content length (RFC 2616 4.3)
options.headers['Content-Length'] = Buffer.byteLength(postData)
// Or other way to handle error
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
}

Simple NodeJS http request equivalent for curl

I'm having trouble converting a curl that works to an equivalent http request through nodeJS. I'm using the Request module, but I seem to be doing something wrong when making the request. When I run it, it gives me
body: Cannot POST /path
Not really sure how to debug this, any ideas?
var data = JSON.stringify({
'sender': {
'name': 'name',
'handle': 'handle'
},
'subject': 'Title here',
'body': 'something something',
'metadata': {}
});
var options = {
host: 'website.com',
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer <token>',
'Accept': 'application/json',
'Content-Length': Buffer.byteLength(data)
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
Below is the equivalent curl (that works) that I'm trying to make for the above nodejs.
curl --include \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <token>" \
--header "Accept: application/json" \
--data-binary "{
\"sender\": {
\"name\": \"name\",
\"handle\": \"handle\"
},
\"subject\": \"Title here\",
\"body\": \"something something\",
\"metadata\": {}
}" \
'website.com/path"
You can include your JSON data directly with json parameter with request library :
var request = require('request');
var options = {
uri: 'http://website.com/path',
method: 'POST',
headers: {
'Authorization': 'Bearer <token>',
'Accept': 'application/json'
},
json: {
'sender': {
'name': 'name',
'handle': 'handle'
},
'subject': 'Title here',
'body': 'something something',
'metadata': {}
}
};
var req = request(options, function(error, response, body) {
if (error) {
console.log(error);
return;
}
if (response.statusCode == 200) {
console.log(body);
} else {
console.log("receive status code : " + response.statusCode);
}
});
From request options doc :
json - sets body to JSON representation of value and adds
Content-type: application/json header. Additionally, parses the
response body as JSON.

Resources