node-twitter: Twitter video media upload not working : Error: HTTP Error: 400 Bad Request

I am trying upload and post video media to the twitter using ‘twitter’ npm package.

During this I am facing an error :

error  Error: HTTP Error: 400 Bad Request
at Request._callback (/Volumes/Office/Work/Pack3/developer/tweet-it/node_modules/twitter/lib/twitter.js:221:9)
at Request.self.callback (/Volumes/Office/Work/Pack3/developer/tweet-it/node_modules/request/request.js:185:22)
at Request.emit (events.js:180:13)
at Request.<anonymous> (/Volumes/Office/Work/Pack3/developer/tweet-it/node_modules/request/request.js:1157:10)
at Request.emit (events.js:180:13)
at IncomingMessage.<anonymous> (/Volumes/Office/Work/Pack3/developer/tweet-it/node_modules/request/request.js:1079:12)
at Object.onceWrapper (events.js:272:13)
at IncomingMessage.emit (events.js:185:15)
at endReadableNT (_stream_readable.js:1101:12)
at process._tickCallback (internal/process/next_tick.js:114:19)

Codebase Initialize library

var Twitter = require('twitter');

All details generate through twitter app console.

var twitterClient = new Twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});


function makePost(endpoint, params) {
        return new Promise(function (resolve, reject) {
            twitterClient.post(endpoint, params, function (error, data, response) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        });
    }

exports.postVideo = async function (req, res, next) {
    var params = req.body;

    const pathToMovie = './medias/video_3_640x360_1mb.mp4';
    const mediaType = 'video/mp4'; // `'video/mp4'` is also supported
    const mediaData = require('fs').readFileSync(pathToMovie);
    const mediaSize = require('fs').statSync(pathToMovie).size;
    console.log('mediaData ', mediaData);

    try {

        var options = {
            command: 'INIT',
            total_bytes: mediaSize,
            media_type: mediaType,
        };

// This request about to complete

        var mediaInit = await makePost('media/upload', options);

        console.log('options ', options);
        console.log('mediaInit ', mediaInit);
        console.log('mediaInit.media_id_string ', mediaInit.media_id_string);

// This request is not working.

        await makePost('media/upload', {
            command: 'APPEND',
            media_id: mediaInit.media_id_string,
            media: mediaData,
            segment_index: 0
        });

        var mediaFinalize = await makePost('media/upload', {
            command: 'FINALIZE',
            media_id: mediaInit.media_id_string,
        });
        console.log('mediaFinalize ', mediaFinalize);
        var status = {
            status: params.status,
            media_ids: mediaFinalize.media_id_string
        };

        twitterClient.post('statuses/update', status, function (error, tweet, response) {
            if (error) {
                return next(error);
            }
            req.twitterStore = tweet;
            return next();
        });
    } catch (error) {
        console.log('error ', error);
        return next(error);
    }
};

Video Used : https://www.sample-videos.com/video/mp4/360/big_buck_bunny_360p_1mb.mp4

Reference : https://github.com/desmondmorris/node-twitter/tree/master/examples#chunked-media

About this issue

Most upvoted comments

I think that my solution was to use another package. Here is how you can solve it with twit. @neer17 @ashatat

twit.postMediaChunked({ file_path: PATH }, (err, data, response) => {
    handleError(err, callback);
    setTimeout(() => {
        getTweet(TEMP_FILENAME, callback).then(res => {
            twit.post('statuses/update', { status: res, media_ids: data.media_id_string }, (err, data, response) => {
                handleError(err, callback);
                callback(null, response)
            });
        });
    }, 3000); // Needed delay for processing of the video
});

hi @ljmocic Twitter does not allow Video and gif to be posted in single upload command. You have to first Init the media upload and then Append the request by using the ID returned from Init.

check this for more details : https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload-append