Simple NodeJS http request equivalent for curl - node.js

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.

Related

Convert Paypal cURL command to Axios request

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()
}
})

Why do I get this error when trying to get my past paypal transactions?

I am trying to read my past transactions. I have already done that with the curl tool, but I can't get it working in nodeJS. I am trying this with the request api. Getting the token from paypal works just fine. Just can't figure out to do this
curl -v -X GET https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer access-token"
in NodeJS currently I have this. Can someone help me pls figuring it out?
var request = require('request');
let token;
request.post({
uri: "https://api.paypal.com/v1/oauth2/token",
headers: {
"Accept": "application/json",
"Accept-Language": "en_US",
"content-type": "application/x-www-form-urlencoded"
},
auth: {
'user': client_id,
'pass': secret,
},
form: {
"grant_type": "client_credentials"
}
}, function (error, response, body) {
let resp = JSON.parse(body);
token = resp.access_token;
console.log(token)
if (error)
console.log(error)
getTransactions();
});
function getTransactions() {
if (!token) {
console.error("Could not get token");
return;
}
request.post({
uri: "https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
headers: {
"content-type": "application/json"
},
auth: {
bearer: token,
}
}, function (error, response, body) {
console.log(body);
console.log(error)
console.log(JSON.stringify(response))
});
}
The Error:
"statusCode":404,"body":"","headers":{"content-length":"0",
"connection":"close","date":"Sun, 21 Jun 2020 00:35:15 GMT",
"cache-control":"max-age=0, no-cache, no-store, must-revalidate",
"paypal-debug-id":"207f5d4c9341",
"strict-transport-security":"max-age=31536000; includeSubDomains"},"request":{"uri":{"protocol":"https:","slashes":true,"auth":null,
"host":"api.paypal.com","port":443,"hostname":"api.paypal.com",
"hash":null,
"search":"?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"query":"start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"pathname":"/v1/reporting/transactions",
"path":"/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"href":"https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00"},
"method":"POST","headers":{"Accept":"application/json",
"Accept-Language":"en_US","content-type":"application/x-www-form-urlencoded",
"authorization":"Bearer accesstoken_is_my_little_secret",
"content-length":0}}}
index.js:38
Your NodeJS is sending a POST request instead of a GET, hence the 404

Why do I get code 404 from paypal when trying to read past transactions

I am trying to read my past transactions. I have already done that with the curl tool, but I can't get it working in nodeJS. I am trying this with the request api. Getting the token from paypal works just fine. Just can't figure out to do this
curl -v -X GET https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer access-token"
in NodeJS currently I have this. Can someone help me pls figuring it out?
var request = require('request');
let token;
request.post({
uri: "https://api.paypal.com/v1/oauth2/token",
headers: {
"Accept": "application/json",
"Accept-Language": "en_US",
"content-type": "application/x-www-form-urlencoded"
},
auth: {
'user': client_id,
'pass': secret,
},
form: {
"grant_type": "client_credentials"
}
}, function (error, response, body) {
let resp = JSON.parse(body);
token = resp.access_token;
console.log(token)
if (error)
console.log(error)
getTransactions();
});
function getTransactions() {
if (!token) {
console.error("Could not get token");
return;
}
request.post({
uri: "https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
headers: {
"content-type": "application/json"
},
auth: {
bearer: token,
}
}, function (error, response, body) {
console.log(body);
console.log(error)
console.log(JSON.stringify(response))
});
}
The Error:
"statusCode":404,"body":"","headers":{"content-length":"0",
"connection":"close","date":"Sun, 21 Jun 2020 00:35:15 GMT",
"cache-control":"max-age=0, no-cache, no-store, must-revalidate",
"paypal-debug-id":"207f5d4c9341",
"strict-transport-security":"max-age=31536000; includeSubDomains"},"request":{"uri":{"protocol":"https:","slashes":true,"auth":null,
"host":"api.paypal.com","port":443,"hostname":"api.paypal.com",
"hash":null,
"search":"?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"query":"start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"pathname":"/v1/reporting/transactions",
"path":"/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00",
"href":"https://api.paypal.com/v1/reporting/transactions?start_date=2020-05-20T01:01:01-00:00&end_date=2020-06-19T01:01:01-00:00"},
"method":"POST","headers":{"Accept":"application/json",
"Accept-Language":"en_US","content-type":"application/x-www-form-urlencoded",
"authorization":"Bearer accesstoken_is_my_little_secret",
"content-length":0}}}
index.js:38

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);
});

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();
}

Resources