Wouter van Dijke
Wouter van Dijke

Reputation: 692

How to post an image to Twitter in Node.js

When I try to upload a PNG image to the Twit library in Node, I get an error.

I'm trying to make a Twitter bot in Node.js that generates a random rgb colour, creates a picture of this colour and tweets it. With some help in another question I now know how to create a canvas as PNG in Node, but I'm not sure how to get it into the Twit library. Using the code below I get an error: 44, message: 'media_ids parameter is invalid.' which appears to be coming from the Twitter API.

The official Twitter documentation says:

You may either upload the raw binary of the file or its base64-encoded contents.

I'm not sure what to do with that. How can I get the Twitter API to accept my canvas as a PNG image?

My code is:

var Twit = require('twit')
var Canvas = require('canvas');
var Image = Canvas.Image;


var T = new Twit({
    consumer_key:         '###'
  , consumer_secret:      '###'
  , access_token:         '###'
  , access_token_secret:  '###'
})

//Generate the canvas
var canvas = new Canvas(800, 800);
var context = canvas.getContext('2d');

function tweet() {

//Generate a random colour
var r = Math.floor((Math.random() * 256));
var g = Math.floor((Math.random() * 256));
var b = Math.floor((Math.random() * 256));
var color = "rgb("+r+","+g+","+b+")";

    // draw box
    context.beginPath();
    context.moveTo(0, 00);
    context.lineTo(0, 800);
    context.lineTo(800, 800);
    context.lineTo(800, 0);
    context.closePath();
    context.lineWidth = 5;
    context.fillStyle = color;
    context.fill();

var fs = require('fs')
  ,  out = fs.createWriteStream(__dirname + '/text.png')   
  , stream = canvas.pngStream();
var dataUrl = canvas.pngStream().pipe(out);
//I'm not sure if this bit is really necessary

    // first we must post the media to Twitter
T.post('media/upload', { media_data: canvas.toBuffer() }, function (err, data, response) {

  // now we can reference the media and post a tweet (media will attach to the tweet)
  var mediaIdStr = data.media_id_string
  var params = { status: color, media_ids: [mediaIdStr] }

  T.post('statuses/update', params, function (err, data, response) {
    console.log(data)
  })
})

}
    setTimeout(tweet, 30000);

Upvotes: 2

Views: 4951

Answers (1)

chrki
chrki

Reputation: 6333

The twitter docs say this about using media/upload:

Parameters

media - The raw binary file content being uploaded. Cannot be used with media_data.

media_data - The base64-encoded file content being uploaded. Cannot be used with media.

You are providing raw data to the media_data parameter here: media_data: canvas.toBuffer()

To fix this upload the image base64-encoded:

T.post('media/upload', { media_data: canvas.toBuffer().toString('base64') }, function (err, data, response) {

Upvotes: 3

Related Questions