taiyoh's memorandum

@ttaiyoh が、技術ネタで気づいたことを書き溜めておきます。

node.jsでtwitterのstatuses/update_with_mediaに対応

var Twitter = require('twitter')
  , request = require('request')
  , fs = require('fs');

Twitter.prototype.updateStatusWithMedia = function(text, params, callback) {
    var self = this
      , oauth = this.oauth
      , form, orderedParameters, r
      , url = 'http://upload.twitter.com/1/statuses/update_with_media.json';
    if (typeof params === 'function') {
        callback = params;
        params = {};
    }

    orderedParameters= oauth._prepareParameters(
        self.options.access_token_key,
        self.options.access_token_secret,
        'POST',
        url
    );
   
    r = request.post(url, callback)
    r.setHeaders({authorization: oauth._buildAuthorizationHeaders(orderedParameters)});
    form = r.form()

     form.append('status', text);
     for (i in params) {
         if (i == 'media[]') {
             form.append(i, fs.createReadStream(params[i]))
         }
         else {
             form.append(i, params[i]);
         }
     }

    return this;
};

var msg = 'API test',
    opt = {'media[]': __dirname+'/path/to/image'};

twit = new Twitter({
    consumer_key        : 'CONSUMER_KEY',
    consumer_secret     : 'CONSUMER_SECRET',
    access_token_key    : 'ACCESS_TOKEN_KEY',
    access_token_secret : 'ACCESS_TOKEN_SECRET',
});
twit.updateStatusWithMedia(msg, opt, function(err, res) {
    if (err) {
        console.log("twitter post error:\n", err);
    }
    else {
        res.setEncoding('utf8');
        var data = JSON.parse(res.body);
        console.log("twitter post success:\n", data);
    }
});

oauthライブラリの_performSecureRequestメソッドでやっているauthorizationヘッダの追加処理を入れて、form-dataライブラリを使ってアップすればOKだった。これなら、boundaryとかmime_typeを一切見る必要なく処理が書ける。