ECMAScript 6thが正式版になったのでPromiseを使ってみたい!
というわけで、Twitter APIにアクセスしてOAuth 1.0のアクセストークンをゲットするコマンドラインツールをPromiseで書いてみました。
OAuth 1.0ではアクセストークンを取得する過程で、ブラウザを開き、PinCodeを取得して入力するといった面倒な処理がありますが、そのPinCodeの入力待ちもPromiseで行っております。
nodeのバージョンはv0.12.4
var request = require('request'); var qs = require('querystring'); var readline = require('readline'); var cp = require('child_process'); var fs = require('fs'); exports.init = function(consumerInfo, file) { var requestInfo; gettingRequestToken(consumerInfo).then(function(data) { requestInfo = data; return waitingPinInput(requestInfo); }).then(function(pinCode) { return gettingAccessToken(consumerInfo, requestInfo, pinCode); }).then(function(accessInfo) { var str = JSON.stringify(accessInfo); fs.writeFileSync(file, str, {mode: 0600}); console.log('Your Access Token Saved!'); process.exit(0); }).catch(function(err) { console.error(err); process.exit(1); }); }; function gettingAccessToken(consumerInfo, requestInfo, pinCode) { return new Promise(function(resolved, rejected) { var oauth = { consumer_key: consumerInfo.consumer_key, consumer_secret: consumerInfo.consumer_secret, token: requestInfo.oauth_token, token_secret: requestInfo.oauth_token_secret, verifier: pinCode }; var url = 'https://api.twitter.com/oauth/access_token'; request.post({url: url, oauth: oauth}, function(err, res, body) { if (err) { rejected(err); return; } if (res.statusCode !== 200) { rejected(new Error('Not OK Response: ' + res.statusCode)); return; } var data = qs.parse(body); resolved(data); }); }); } function waitingPinInput(requestInfo) { var AUTHORIZE_URL = 'https://api.twitter.com/oauth/authorize' + '?oauth_token='; cp.exec('open ' + AUTHORIZE_URL + requestInfo.oauth_token); // OSX専用 return new Promise(function(resolved, rejected) { var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Input Pin Code: ', function(answer) { resolved(answer); }); }); } function gettingRequestToken(info) { return new Promise(function(resolved, rejected) { var oauth = { consumer_key: info.consumer_key, consumer_secret: info.consumer_secret }; var url = 'https://api.twitter.com/oauth/request_token'; request.post({url: url, oauth: oauth}, function(err, res, body) { if (err) { rejected(err); return; } if (res.statusCode !== 200) { rejected(new Error('Not OK Response: ' + res.statusCode)); return; } var data = qs.parse(body); resolved(data); }); }); }
var token = require('./token'); token.init({ consumer_key: "hogehoge", consumer_secret: "fugafuga" }, 'token.txt')
nodeで定番のasyncに比べて便利というわけでもないですが、promiseのチェインは結構書きやすいです。