Question

I'm attempting to post an image onto the twitter api, v1.1 I've tried just about all the example out there, and nothing seems to be able to post it. include Posting images to twitter in Node.js using Oauth

I'm using the oauth library mentioned there, and I also had jsOauth, which I thought I'd give a shot according to https://gist.github.com/lukaszkorecki/1038408

Nothing has worked, and at this point I'm starting to lose hope on whether I can even do this.

 function postStatusWithMedia(status, file) {
var err = new Object();
if(fs.existsSync(file) === false) {
    err.message = "File not found :(";
    parseTwitterError(err);
} else {
    var oauth = OAuth(options = {
        "consumerKey": consumer_key,
        "consumerSecret": consumer_secret,
        "accessTokenKey": access_token,
        "accessTokenSecret": access_token_secret
    });

    callbacks = {
                onSuccess : function() {
                    console.log('upload worked!')
                },
                onFailure : function() {
                    console.log('upload failed!');
                    console.dir(arguments);
                }
    },

    uploadData = {
        'status' : status,
        'media' : Base64.encode(fs.readFileSync(file))
    };

        oauth.post('https://api.twitter.com/1.1/statuses/update_with_media.json',uploadData, callbacks.onSuccess, callbacks.onFailure);

    return false;
}
 }

If it can't be done, can you please explain why? Otherwise, anything that could lead me to the right direction would be great.

Was it helpful?

Solution

var fs = require('fs');
var request = require('request');
var FormData = require('form-data');
var utf8 = require('utf8');

// Encode in UTF-8
status = utf8.encode(status);

var form = new FormData();
form.append('status', status)
form.append('media[]', fs.createReadStream(file));

// Twitter OAuth
form.getLength(function(err, length){
    if (err) {
        return requestCallback(err);
    }
    var oauth = { 
            consumer_key: consumer_key,
            consumer_secret: consumer_secret,
            token: access_token,
            token_secret: access_token_secret
    };
    var r = request.post({url:"https://api.twitter.com/1.1/statuses/update_with_media.json", oauth:oauth, host: "api.twitter.com", protocol: "https:"}, requestCallback);
    r._form = form;
    r.setHeader('content-length', length);
});

function requestCallback(err, res, body) {
    if(err) {
        throw err;
    } else {
        console.log("Tweet and Image uploaded successfully!");
    }
}

I ended up using request and node-form-data to manually construct a multipart/form-data request and send it with the status request, utf8 was for encoding the status into UTF-8, not doing so caused issues with '<3' and other characters.

OTHER TIPS

I have not tested these code.Its from my colleague.sure the code is working. Perhaps this will help.

//twitter_update_with_media.js

   (function() {
    var fs, path, request, twitter_update_with_media;

    fs = require('fs');

    path = require('path');

    request = require('request');


    twitter_update_with_media = (function() {
        function twitter_update_with_media(auth_settings) {
            this.auth_settings = auth_settings;
            this.api_url = 'https://api.twitter.com/1.1/statuses/update_with_media.json';
        }

        twitter_update_with_media.prototype.post = function(status, imageUrl, callback) {
            var form, r;
            r = request.post(this.api_url, {
                oauth: this.auth_settings
            }, callback);
            form = r.form();
            form.append('status', status);
            return form.append('media[]', request(imageUrl));
        };

        return twitter_update_with_media;

    })();

    module.exports = twitter_update_with_media;
}).call(this);

next file //upload_to_twitter.js

            var tuwm = new twitter_update_with_media({
                consumer_key: TWITTER_OAUTH_KEY,
                consumer_secret: TWITTER_OAUTH_SECRET,
                token: access[0],
                token_secret: access[1]
            });

    media_picture.picture = imageURL;

                if (media_picture.picture) {
                    console.log('with media upload');

                    request.head(media_picture.picture,
                        function (error, response, body) {
                        if (!error && response.statusCode == 200) {
                            var image_size = response.headers['content-length'];
                            if (image_size > 2000000) { // 2mb max upload limit
                                console.log('greater than 2mb');
                                sendMessageWithoutImage(err, req, res, next, twit, wallpost, access);

                            } else {
                                console.log('less than 2mb');
                                console.log('twitter text', content);
                                tuwm.post(content, media_picture.picture, function(err, response) {
                                    if (err) {
                                        console.log('error', err);
                                        return next(err);
                                    }
                                    error_parse = JSON.parse(response.body);
                                    console.log('with media response', response.body);

                                    if (error_parse.errors) {
                                        console.log('have errors', error_parse);
                                        res.json({
                                            status: 500,
                                            info: error_parse.errors[0].code + ' ' + error_parse.errors[0].message

                                        });
                                    } else {
                                        res.json({
                                            status: 200,
                                            info: "OK",
                                            id: response.id
                                        });
                                    }
                                });

                            }
                        }
                    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top