Box API Irregular Headers - node.js

I am trying to upload an image with the box API and the request module. I tried the provided curl example without any problems.
I have a request all setup like this
var request = require("request");
var fs = require("fs");
var path = require("path");
request({
url: "https://api.box.com/2.0/files/content",
method: "POST",
form: {
filename: fs.createReadStream(path.join(__dirname, "midguts.jpg")),
folder_id: "0"
},
headers: {
api_key: "<API_KEY>",
auth_token: "<AUTH_TOKEN>"
}
}, function (error, response, body) {
console.log(error);
console.log(body);
});
The problem arises when I get to the headers part. The box API call for a headers string of
"Authorization: BoxAuth api_key=API_KEY&auth_token=AUTH_TOKEN"
but I with the request module I can only send an object of key, value pairs. I also looked at the docs for nodes http.request and found it has the same issue.
So the question is, why does the API not follow the standard key pair format and how can I send a POST request that will work?

Authorization is the name of the HTTP Header (see also). This might work better:
headers: {
Authorization: "BoxAuth api_key=API_KEY&auth_token=AUTH_TOKEN"
}

Related

node.js how to send multipart form data in post request

I am attempting to get data in the form of an image sent from elsewhere using multipartform, however when trying to understand this via the great sanctuary(stack overflow) there are missing elements I don't quite understand.
const options = {
method: "POST",
url: "https://api.LINK.com/file",
port: 443,
headers: {
"Authorization": "Basic " + auth,
"Content-Type": "multipart/form-data"
},
formData : {
"image" : fs.createReadStream("./images/scr1.png")
}
};
request(options, function (err, res, body) {
if(err) console.log(err);
console.log(body);
});
2 questions:
what is the variable auth, what do I initialize it to/where/how do I declare it
what is the url "api.LINK.com", is this just the site url where this code is on
After your comments I think I may be doing this wrong. The goal is to send data(an image) from somewhere else(like another website) to this node app, then the nodeapp uses the image and sends something back.
So that I would be the one creating the API endpoint

Unable to exchange code for access token in node.js. Mailchimp API

I am trying to use OAuth2 with the Mailchimp API, and I am following their documentation to the letter, but I am unable to complete step 4. At this step, I exchange the code I received from the authorization screen for the token. Per the documentation, this can be done in curl like so:
curl --request POST \
--url 'https://login.mailchimp.com/oauth2/token' \
--data "grant_type=authorization_code&client_id={client_id}&client_secret={client_secret}&redirect_uri={encoded_url}&code={code}" \
--include
I attempted to convert this to work on node.js by writing this:
var dataString = 'grant_type=authorization_code&client_id=' + clientid + '&client_secret=' + clientsecret + '&redirect_uri=' + encodedurl + '&code=' + url.parse(req.url, true).query.code;
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
data: dataString
};
function callback(error, response, body) {
if (!error) {
console.dir(JSON.stringify(body));
}
else{
console.dir(error);
}
}
request(options, callback);
When I make the request.debug = true, I see that I am getting a 400 error. The message sent to the console is a bunch of garbled characters though. When I use these same variables and endpoints to authenticate through Postman though, it works fine, so the issue is not with the variables or the API itself.
I am not entirely sure what I am doing wrong here. The request I am making seems almost identical what is written in curl in the documentation. So where am I going wrong?
Hmm, did you forget to define request?
var request = require("request");
Finally figured it out. The issue was in the header of the request. There are two ways to fix this. The first is to use "form" instead of "data". Request includes a "content-type: x-www-form-urlencoded" header automatically if the option "form" is used.
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
form: dataString
};
I am not sure what header is used when the "data" option is used, or if no content-type is declared at all. Either way, if you choose to continue to use the "data" option, you can manually declare a content-type header. This is the second possible solution.
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded' },
body: dataString
};
After alot of tries, I figured out. You can use code only once. So make sure you use code you get from redirect URI only once.
With new code use this code
const dataString = "grant_type=authorization_code&client_id="+client_id+"&client_secret="+client_secret+"&redirect_uri="+redirect_uri+"&code="+req.body.code
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
headers:
{
'Content-Type': 'application/x-www-form-urlencoded',
},
form: dataString
};
function callback(error, response, body) {
if (!error) {
let str = JSON.stringify(body)
res.setHeader("Content-Type", "application/json; charset=utf-8")
res.send(body)
}
else{
console.dir(error);
res.send(error)
}
}
request(options, callback);

I can't access cookie returned after http post in NodeJS

I have a simple NodeJS app which authenticates with remote Java CMS. On successful authentication the CMS returns a cookie.
However, for the life of me I can't figure how to access / get this cookie value. (I need the cookie in order to make requests to the CMS's API, once authenticated).
I get the cookie returned in a curl command ok but can't access it in NodeJS.
Curl Command:
curl -v -k --data "username=admin&password=password111&realm=cms101"
https://test.abeo.ie/gatekeeper/rs/authenticate/login
Now here is my NodeJS app's code:
//disable self-signed ssl cert rejection
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var http = require('http');
var request = require('request');
var Cookies = require('cookies');
//enable cookies
request.defaults({jar: true});
request({
url: 'https://test.abeo.ie/gatekeeper/rs/authenticate/login', //URL to hit
qs: {username: 'admin', password: 'password111', realm: 'cms101'}, //Query string data
method: 'POST', //Specify the method
headers: { //We can define headers too
'Content-Type': 'application/x-www-form-urlencoded'
}
},
function(error, response, body){
if(error) {
console.log(error);
} else {
//response.cookie comes out as 'undefined'
console.log(response.statusCode, body, response.cookie);
}
})
So my question is: How do I read the cookie value from the response as the response.cookie value prints out as undefined.
Thanks,
Mike
** If this question seems to vague... Just say so and I will clear it up.
I think I have just answered my question :)
I had the syntax wrong and instead of
console.log(response.statusCode, body, response.cookie);
I needed
console.log(response.statusCode, body, response.headers['set-cookie']);
Just working on parsing the thing now :)

Mailchimp API v3.0 add email to list via NodeJS http

I'm using NodeJS to call the new MailChimp 3.0 API in order to add an email to a list. While I can get it working via POSTman, I'm having a hard time with Node's http:
var http = require('http');
var subscriber = JSON.stringify({
"email_address": "test#test.com",
"status": "subscribed",
"merge_fields": {
"FNAME": "Tester",
"LNAME": "Testerson"
}
});
var options = {
host: 'https://us11.api.mailchimp.com',
path: '/3.0/lists/<myListID>/members',
method: 'POST',
headers: {
'Authorization': 'randomUser myApiKey',
'Content-Type': 'application/json',
'Content-Length': subscriber.length
}
}
var hreq = http.request(options, function (hres) {
console.log('STATUS CODE: ' + hres.statusCode);
console.log('HEADERS: ' + JSON.stringify(hres.headers));
hres.setEncoding('utf8');
hres.on('data', function (chunk) {
console.log('\n\n===========CHUNK===============')
console.log(chunk);
res.send(chunk);
});
hres.on('end', function(res) {
console.log('\n\n=========RESPONSE END===============');
});
hres.on('error', function (e) {
console.log('ERROR: ' + e.message);
});
});
hreq.write(subscriber);
hreq.end();
Rather than getting even some sort of JSON error from Mailchimp, however, I'm getting HTML:
400 Bad Request
400 Bad Request
nginx
Is it clear at all what I"m doing wrong here? It seems pretty simple, yet nothing I've tried seems to work.
A few additional thoughts:
While http's options have an "auth" property, I'm using the headers instead to ensure the authorization is sent without the encoding (as mentioned here). Still, I've also tried with the "auth" property, and I get the same result.
I'm actually making this call from inside an ExpressJS API (my client calls the Express API, that calls the above code - I've edited all that out of this example for simplicity). That's why my variables are "hres" and "hreq", to distinguish them from the "res" and "req" in Express. Is there any reason that could be the issue?
As mentioned above, I am able to get successful results when using POSTman, so I at least know my host, path, list ID, and API key are correct.
It turns out this had a very simple solution: the "host" property of the options object needed to have only the domain name. IE, remove the "https://" protocol:
var options = {
host: 'us11.api.mailchimp.com',
path: '/3.0/lists/<myListID>/members',
method: 'POST',
headers: {
'Authorization': 'randomUser myApiKey',
'Content-Type': 'application/json',
'Content-Length': subscriber.length
}
}
Try this , its working fine for Me.
var request = require('request');
function mailchimpAddListCall(email, cb){
var subscriber = JSON.stringify({
"email_address": email,
"status": "subscribed"
});
request({
method: 'POST',
url: 'https://us13.api.mailchimp.com/3.0/lists/<Your list id>/members',
body: subscriber,
headers:
{
Authorization: 'apikey <your Mailchimp API key>',
'Content-Type': 'application/json'
}
},
function(error, response, body){
if(error) {
cb(err, null)
} else {
var bodyObj = JSON.parse(body);
console.log(bodyObj.status);
if(bodyObj.status === 400){
cb(bodyObj.detail, null);
}
var bodyObj = JSON.parse(body);
cb(null, bodyObj.email_address +" added to list.");
}
});
}
request is a node module, that you'll need to install into your package.json. npm install --save request
You can use the auth properties just fine with API v3, but if you're getting a 400, that's not the problem. The body of the 400 Error should provide more detailed information, but one thing that jumps out immediately: MailChimp doesn't allow fake or fake-looking emails to be added to lists (like test#test.com), so I'd try a real address and see if that works for you.

How do I duplicate this CURL request within nodejs?

I am trying to duplicate the following CURL request within nodejs using request-promise (eventually, I need to use promises so I would prefer this method):
curl -H "Authorization: Token token=[API Key]" -H "Accept: application/vnd.moonclerk+json;version=1" https://api.moonclerk.com/customers
The following code snippet shows my attempt:
var rp = require('request-promise');
var querystring = require('querystring');
//this is what I think is causing me trouble
var bodyHeaders = querystring.stringify({
"Authorization": "Token token=[token taken out in code snippet]",
"Accept": "application/vnd.moonclerk+json;version=1"
});
var options = {
uri: 'https://api.moonclerk.com/customers',
method: 'GET',
body: bodyHeaders
};
var cb = function () {
return function (response) {
console.log("response: ", response);//this should spit out the JSON text I'm looking for
}
}
rp(options).then(cb())
But I am getting Possibly unhandled StatusCodeError: 401 - HTTP Token: Access denied. in the nodejs console as a response. What's the issue here?
PS -- Note that my uri is an HTTPS (i.e., 'https://api.moonclerk.com/customers'); is this what's causing the problem?
You can't pass HTTP headers in the request body, server can't recognize them there. See https://github.com/request/request#custom-http-headers for correct usage of the request library.
var options = {
// ...
headers: {
"Authorization": "Token token=[token taken out in code snippet]",
"Accept": "application/vnd.moonclerk+json;version=1"
}
});

Resources