Asana POST Task - node.js

I am trying to post a task in asana with the following node/express function
exports.addTask = function(req, res) {
var url ='/api/1.0/tasks?workspace=' + req.session.workspace_id
var postBase = "app.asana.com";
var options = {
host: postBase,
port: 443,
path: url,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + JSON.parse(req.session.user).access_token,
}
};
var req2 = https.request(options, function(res2) {
res2.on('data', function(chunk) {
console.log(chunk + "");
});
res2.on('error', function(e){
console.log(e.message);
});
});
req2.end();
}
I get the correct response back from asana which is:
{"data":{"id":8253508011735,"created_at":"2013-10-20T16:17:53.140Z","modified_at":"2013-10-20T16:17:53.140Z","name":"","notes":"","completed":false,"assignee_status":"upcoming","completed_at":null,"due_on":null,"workspace":{"id":1361701377437,"name":"getspur.com"},"assignee":null,"parent":null,"followers":[{"id":1050147548705,"name":"Gorkem Yurtseven"}],"projects":[],"tags":[]}}
but nothing seems to be added in my asana tasks..
ps. I am currently at the Facebook Hackathon in New York,so bring it on!

It could be because the assignee is null, and it's not in any projects - that basically makes it impossible to find (except perhaps via Search?)
Without seeing the post body I'm not sure if that's intentional or just a formatting issue.

Related

nodejs requestify.request() crashes when the method is given in the options

Why does requestify.request() crash because it doesn't think it was given the method POST
var postBody = querystring.stringify(dat);
var postOptions = {
host: 'https://www.example.com'
, path: '/admin'
, method: 'post' // POST, 'POST', post
, headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postBody) }
};
var postReq = requestify.request(postOptions, function (err, resp, respBody) {
resp.setEncoding('utf8');
resp.on('data', function (chunk) {
console.log('Response: ' + chunk);
});
});
It looks like you are using an old version of the documentation for the newer version of requestify
Read the API reference section of https://github.com/ranm8/requestify
And read just a little lower down it see a requestify.request() example.
Options doesn't have host, path, ...

Unable to authenticate with Google token in Node JS

On a Node server, I am trying to validate a Google user but it always returns with a "Bad Request". What is wrong in my code?
var post_data = querystring.stringify({
'alt': 'json',
'access_token': <token from REST API params>
});
var post_options = {
host: 'www.googleapis.com',
port: '443',
path: '/oauth2/v1/userinfo',
method: 'GET',
headers: {
'Content-Length': Buffer.byteLength(post_data)
}
};
var post_req = https.request(post_options, function (result) {
if (result.statusCode == 200) {
result.on('data', function (chunk) {
//Valid user stuff
});
}
else {
//Invalid user stuff
}
});
post_req.write(post_data);
post_req.end();
The scenario here is that my client app is a chrome extension that successfully gets a token. The token is passed to my REST API hosted on the Node server. I try to replay that token to authenticate the Google user. (Note that if I use the token on the Chrome extension to make the same request, it succeeds and I get the profile information! It's only the request on the Node server that fails.) Help me! Please?
The problem is that you are:
Using the property host instead of hostname
Providing the port parameter (not sure about this one, but it will work without it)
Method should be POST, not GET
So, your new post_options object should be:
var post_options = {
hostname: 'www.googleapis.com',
path: '/oauth2/v1/userinfo',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(post_data)
}
};
If you want to make it easier on yourself you could use a module such as google-auth-library or google-sign-in.

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 to upload assets to a github release from node.js

I am trying to automatically post some assets on a Github release I programmatically create.
Here is my upload function:
function uploadFile(fileName, uploadUrl, callback){
var uploadEndPoint = url.parse(uploadUrl.substring(0,uploadUrl.indexOf('{')));
options.host = uploadEndPoint.hostname;
options.path = uploadEndPoint.pathname+'?name=' + fileName;
options.method = 'POST';
options.headers['content-type'] = 'application/zip';
var uploadRequest = https.request(options, callback);
uploadRequest.on('error', function(e) {
console.log('release.js - problem with uploadRequest request: ' + e.message);
});
var readStream = fs.ReadStream(path.resolve(__dirname,'builds',fileName));
readStream.pipe(uploadRequest);
readStream.on('close', function () {
req.end();
console.log('release.js - ' + fileName + ' sent to the server');
});
}
At the end of this I get a 404 not found
I tried auth from token and user/password
I checked the url
I though it might be because of SNI, but I don't know how to check that.
Any clue ? Thanks !
I found a solution to that problem by NOT using the low level node.js modules and using instead restler which is a library that handles SNI.
Here is how is used it:
rest = require('restler'),
path = require('path'),
fs = require('fs');
fs.stat(path.resolve(__dirname,'builds',fileName), function(err, stats){
rest.post(uploadEndPoint.href+'?name=' + fileName, {
multipart: true,
username: GITHUB_OAUTH_TOKEN,
password: '',
data: rest.file(path.resolve(__dirname,'builds',fileName), null, stats.size, null, 'application/zip')
}).on('complete', callback);
});
Hope that will help someone :)
EDIT on 27/02/2015: We recently switched from restler to request.
var
request = require('request'),
fs = require('fs');
var stats = fs.statSync(filePath);
var options = {
url: upload_url.replace('{?name}', ''),
port: 443,
auth: {
pass: 'x-oauth-basic',
user: GITHUB_OAUTH_TOKEN
},
json:true,
headers: {
'User-Agent': 'Release-Agent',
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/zip',
'Content-Length': stats.size
},
qs: {
name: assetName
}
};
// Better as a stream
fs.createReadStream(filePath).pipe(request.post(options, function(err, res){
// Do whatever you will like with the result
}));
The upload_uri can be retrieved through a get request on an existing release or in the response directly after the release creation.

nodejs app - download file from sharepoint with NTLM AUTH

I must confess I'm stuck. I need a nodejs app to download a file from a SharePoint library. Simple, huh? No. Not the simple OOTB SharePoint. The only-ssl allowed, with specific mandatory header added and surely only domain-based NTLM authentication method.
I've tried httpntlm (https://www.npmjs.org/package/httpntlm) that seemed to just might work in advance, but no. The SP responses with something went wrong message.
I've tried node-sharepoint, but it doesn't support NTLM yet. The app gets ETIMEDOUT response.
Any ideas, please welcome.
I am able to download the file using httpntlm module.you need to change the few lines of code.Replace the waterfall logic with below code in httpntlm.js.
async.waterfall([
function ($){
var type1msg = ntlm.createType1Message(options);
httpreq.get(options.url, {
headers:{
'Connection' : 'keep-alive',
'Authorization': type1msg
},
agent: keepaliveAgent
}, $);
},
function (res, $){
if(!res.headers['www-authenticate'])
return $(new Error('www-authenticate not found on response of second request'));
var type2msg = ntlm.parseType2Message(res.headers['www-authenticate']);
var type3msg = ntlm.createType3Message(type2msg, options);
if(method!=='download'){
httpreq[method](options.url, {
headers:{
'Connection' : 'Close',
'Authorization': type3msg
},
allowRedirects: false,
agent: keepaliveAgent
}, $);
}else{
//By Dheeraj for file download
httpreq.download(
url,
{
headers:{
'Connection' : 'Close',
'Authorization': type3msg
},
//allowRedirects: false,
agent: keepaliveAgent
},
__dirname + 'your_filename',
function (err, progress){
if (err) return console.log(err);
console.log(progress);
}, function (err, res){
if (err) return console.log(err);
console.log(res);
});
}
}
], callback);
};
['get', 'put', 'post', 'delete', 'head','download'].forEach(function(method){
exports[method] = exports.method.bind(exports, method);
});
and replace download method of httpreq.js(httpntm_module/node_modules/httpreq_module/httpreq.js) You can find it at Line number 79 approx.
exports.download = function (url,options, downloadlocation, progressCallback, callback) {
//var options = {};
options.url = url;
options.method = 'GET';
options.downloadlocation = downloadlocation;
options.allowRedirects = true;
// if only 3 args are provided, so no progressCallback
if(callback === undefined && progressCallback && typeof(progressCallback)==="function")
callback = progressCallback;
else
options.progressCallback = progressCallback;
doRequest(options, callback);
}
Please let me know if you are still getting issues.

Resources