Posting images to twitter in Node.js using Oauth


I'm trying to post images to Twitter using the Oauth module. Here is what I have:

It throws a 403 error, I know im doing something wrong with how I add the media to the post but Im just not sure where to go from here.

var https = require('https');
var OAuth= require('oauth').OAuth;
var keys = require('./twitterkeys');
var twitterer = new OAuth(

var params = {
    status : "Tiger!",
    media : [("data:" + mimeType + ";base64,") + fs.readFileSync(path,'base64')]

//function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback)"",
           keys.token, keys.secret, params, "multipart/form-data",
           function (error, data, response2) {
               console.log('Error: Something is wrong.\n'+JSON.stringify(error)+'\n');

               console.log('Twitter status updated.\n');

Here is what I belive im supose to be doing but I don't know how to do that in the Node.js Oauth module. Posting image to twitter using Twitter+OAuth

Problem courtesy of: Adam Magaluk


Reviewing the code, it looks like there's no multipart/form-data handling at all in the node-oauth package right now. You can still use the node-oauth function to create the authorization header, but you'll have to do the multipart stuff on your own.

There are probably third-party libraries that can help out with that, but here's how I got it to work constructed by hand.

var data = fs.readFileSync(fileName);
var oauth = new OAuth(
    twitterKey, twitterSecret,
    '1.0', null, 'HMAC-SHA1');

var crlf = "\r\n";
var boundary = '---------------------------10102754414578508781458777923';

var separator = '--' + boundary;
var footer = crlf + separator + '--' + crlf;
var fileHeader = 'Content-Disposition: file; name="media"; filename="' + photoName + '"';

var contents = separator + crlf
    + 'Content-Disposition: form-data; name="status"' + crlf
    + crlf
    + tweet + crlf
    + separator + crlf
    + fileHeader + crlf
    + 'Content-Type: image/jpeg' +  crlf
    + crlf;

var multipartBody = Buffer.concat([
    new Buffer(contents),
    new Buffer(footer)]);

var hostname = '';
var authorization = oauth.authHeader(
    accessToken, tokenSecret, 'POST');

var headers = {
    'Authorization': authorization,
    'Content-Type': 'multipart/form-data; boundary=' + boundary,
    'Host': hostname,
    'Content-Length': multipartBody.length,
    'Connection': 'Keep-Alive'

var options = {
    host: hostname,
    port: 443,
    path: '/1/statuses/update_with_media.json',
    method: 'POST',
    headers: headers

var request = https.request(options);     

request.on('error', function (err) {
    console.log('Error: Something is wrong.\n'+JSON.stringify(err)+'\n');

request.on('response', function (response) {            
    response.on('data', function (chunk) {
    response.on('end', function () {
        console.log(response.statusCode +'\n');
Solution courtesy of: Dax Fohl


There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.