How can I upload multiple images to twitter?

Viewed 333

I am really new to nodejs and javascript. I am trying to create a twitter bot that post tweets with two images. However, all implementations I have came across use single media upload that only helps with a single image file.

const Twitter = require("twitter")
const fs = require("fs")

const client = new Twitter({
  consumer_key: process.env.CONSUMER_KEY,
  consumer_secret: process.env.CONSUMER_SECRET,
  access_token_key: process.env.ACCESS_TOKEN_KEY,
  access_token_secret: process.env.ACCESS_TOKEN_SECRET
})

const imageData1 = fs.readFileSync("./quote.jpg"); 
const imageData2 = fs.readFileSync("./meaning.jpg"); // the second image i want to upload

client.post("media/upload", {media: imageData1}, function(error, media, response) {
  if (error) {
    console.log(error)
  } else {
    const status = {
      status: "I tweeted from Node.js!",
      media_ids: media.media_id_string
    }
    console.log(media)

    client.post("statuses/update", status, function(error, tweet, response) {
      if (error) {
        console.log(error)
      } else {
        console.log("Successfully tweeted an image!")
      }
    })
  }
})

Any help about a different approach or anything that i am doing wrong is appreciated. Cheers!

1 Answers

I was able to do this with the Twit library

You need to upload each image individually, then add the id for this new piece of media to an array. When all images are uploaded, call the statuses/update endpoint with the array of media ids, and the images will be attached to the tweet

const Twit = require('twit')
const fs = require('fs');

const client = new Twit({
    consumer_key: '<CONSUMER_KEY>',
    consumer_secret: '<CONSUMER_SECRET>',
    access_token: '<ACCESS_TOKEN>',
    access_token_secret: '<ACCESS_TOKEN_SECRET>'
});

const files = ['image1.png', 'image2.png'];
const status = 'This tweet has multiple images';
tweetImages(files, status);

function tweetImages(files, status) {
  let mediaIds = new Array();
  files.forEach(function(file, index) { 
    uploadMedia(file, function(mediaId) {
      mediaIds.push(mediaId);
      if (mediaIds.length === files.length) {
        updateStatus(mediaIds, status);
      }
    });
  });
};

function uploadMedia(file, callback) {
  client.post('media/upload', { media: fs.readFileSync(file).toString("base64") }, function (err, data, response) {
    if (!err) {
      let mediaId = data.media_id_string;
      callback(mediaId);
    } else {
      console.log(`Error occured uploading content\t${err}`);
      process.exit(-1);
    }
  });
}

function updateStatus(mediaIds, status) {
  let meta_params = {media_id: mediaIds[0]};
  client.post('media/metadata/create', meta_params, function (err, data, response) {
    if (!err) {
      let params = { status: status, media_ids: mediaIds};
      client.post('statuses/update', params, function (err, data, response) {
        if (err) {
          console.log(`Error occured updating status\t${err}`);
        }
      });
    } else {
      console.log(`Error creating metadata\t${err}`);
      process.exit(-1);
    }
  });
}
Related