Introduction to Mastodon bots

Before you start making bots, consider reading these essays and articles. Also worth browsing: resources for cleaning up your bot's language.

It’s been a few weeks since the big exodus of creative botmakers from Twitter, mainly due to the recent changes to the platform (and, well, other reasons). Some of them gave up on making art bots altogether, but many tried to find a new home for their bots. And some of them ended up on Mastodon.

Mastodon has a very easy to use API, so it’s a great replacement for Twitter if you’d like to experiment with generative art, natural language processing, or make a useful tool that posts updates on weather, or bills being passed by your government. As a bonus, you can easily get an RSS feed of your bot’s posts.

This tutorial has three parts.

  1. First, we will need to create a new Mastodon account for our bot and set up a Mastodon app.
  2. The main section below will show you how to use the generative-art-bot starter project on Glitch.
  3. And finally, we will use cron-job.org to run your bot by periodically pinging your Glitch app.

Once you set up your bot account, open this generative-art-bot starter project. If you’re not already using Glitch, you don’t need to sign up for an account right away. Remixing will create a temporary project for you to test things out.

To remix a project on Glitch, click the “Remix This” button.

 

Next, update your .env file (see the sidebar on the left) with your Mastodon access token. For MASTODON_API you can use https://botsin.space/api/v1/. Also update the value of BOT_ENDPOINT. This can be anything, for example 12345. You will then be able to use the URL of your project together with the endpoint with a site like cron-job.org to wake up your bot and do something. (I’ll explain this part in the final step of this tutorial.)

The Glitch project is structured so that the code for your bot goes inside bot.js. Here we load one of the generators (see the generators folder) that will produce our image, and then we can either share it on Mastodon, or Twitter, or both.

For this tutorial, let’s try the triangular mesh generator.

Delete the content of your bot.js file so that we have a fresh start and add this:

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

helpers is a module that has a few helper functions, for example random_from_array, which will let us change up the text of the bot’s status message every time it posts. And color-scheme is a library that lets you generate color palettes, which we can use for our artwork.

And this is what connects the bot.js file with the main app that powers our bot:

module.exports = function(){

}

The code inside this exported function is what runs when you visit your bot’s endpoint URL.

First, let’s set up messages for our bot to pick from when it posts:

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

module.exports = function(){

  var status_text = helpers.random_from_array([
        'Check this out!',
        'New picture!',
        'Just look at that!'
      ]);
}

Next, we’re going to need some colors. I’m going to go with the petals color scheme from colourlovers.com. And I’m going to have the bot post images with the size of 1200x500px.

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

module.exports = function(){

  var status_text = helpers.random_from_array([
        'Check this out!',
        'New picture!',
        'Just look at that!'
      ]);
  }

  var options = {
        width: 1200,
        height: 500,
        colors: ['571014', 'D4292F', 'FC5978', 'FE7B35', 'FBAC00']
      };

Now, let’s generate a random triangular mesh using our settings.

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

module.exports = function(){

  var status_text = helpers.random_from_array([
        'Check this out!',
        'New picture!',
        'Just look at that!'
      ]);

  var options = {
        width: 1200,
        height: 500,
        colors: ['571014', 'D4292F', 'FC5978', 'FE7B35', 'FBAC00']
      };

  generators.triangular_mesh(options, function(err, image){


  });

}

And now we’re ready to share our art.

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

module.exports = function(){

  var status_text = helpers.random_from_array([
        'Check this out!',
        'New picture!',
        'Just look at that!'
      ]);

  var options = {
        width: 1200,
        height: 500,
        colors: ['571014', 'D4292F', 'FC5978', 'FE7B35', 'FBAC00']
      };

  generators.triangular_mesh(options, function(err, image){
    mastodon.post_image(status_text, image.path, function(err, data){


    });
  });

}

As a final touch, let’s log whether the bot did in fact post the image, and an error message if it didn’t so that we can debug the problem.

This is what your bot.js file should look like:

var helpers = require(__dirname + '/helpers.js'),
    generators = {
      triangular_mesh: require(__dirname + '/generators/triangular-mesh.js'),
    },
    mastodon = require(__dirname + '/bot/fediverse/mastodon.js');

module.exports = function(){

  var status_text = helpers.random_from_array([
        'Check this out!',
        'New picture!',
        'Just look at that!'
      ]);

  var options = {
        width: 1200,
        height: 500,
        colors: ['571014', 'D4292F', 'FC5978', 'FE7B35', 'FBAC00']
      };

  generators.triangular_mesh(options, function(err, image){
    mastodon.post_image(status_text, image.path, function(err, data){
      if (err){
        console.log('oh no...', err)
      } else {
        console.log('image was posted!');
        console.log(data.url);
      }
    });
  });

}

Perfect.

Before we generate our first artwork, let’s pull up the log, so we can see what the bot is doing. You can open the Activity Log using the Log button under your project icon.

 

And now you can go to the endpoint URL of your bot (you can click the “Show” button on top of the page to see the URL of your project, and then add /BOT_ENDPOINT at the end, just like in the example I used earlier:

https://generative-art-bot.glitch.me/12345

Open this URL in a new browser tab or window — and you will see this in your Activity Log back in the Glitch editor:

You can copy the URL from the log to see your bot’s post:

Every time you visit the endpoint URL a new image will be generated. (I will explain later in this tutorial how to do this automatically.)

Now, time to experiment a little bit.

Let’s look at what’s actually inside generators/triangular-mesh.js and maybe poke around, to see if we can make the bot’s output more fun and interesting.

When you open the file, you will see a link to the tutorial that inspired this generator. We see how the options are being set up. (I’ll get to the animate option in a little bit.)

The generator uses something called canvas to make your image, which is an HTML element designed just for that. We can see a function called drawTriangle, which, we might correctly assume draws the triangles. It looks pretty straightforward, let’s change it up a bit. How about adding a smaller triangle inside the triangle?

  function drawTriangle(pointA, pointB, pointC) {
    ctx.beginPath();
    ctx.moveTo(pointA.x, pointA.y);
    ctx.lineTo(pointB.x, pointB.y);
    ctx.lineTo(pointC.x, pointC.y);
    ctx.lineTo(pointA.x, pointA.y);
    ctx.closePath();
    ctx.fillStyle = '#' + helpers.random_from_array(options.colors); 
    ctx.fill();
    ctx.stroke();

    /* Adding new code for a smaller triangle.*/

    ctx.beginPath();
    ctx.moveTo(pointA.x + 10, pointA.y - 10);
    ctx.lineTo(pointB.x - 10, pointB.y - 10);
    ctx.lineTo(pointC.x - 10, pointC.y + 10);
    ctx.lineTo(pointA.x + 10, pointA.y - 10);
    ctx.closePath();
    ctx.fillStyle = '#' + helpers.random_from_array(options.colors); 
    ctx.fill();
    ctx.stroke();

  }

There is a little bit of math involved, as with all good art, but all I’m doing is moving the points closer to the center. Let’s go back to our bot’s endpoint URL and see what this does.

Alright, this is not exactly what I had in mind, I calculated the points of the inner triangle wrong. But it actually looks good! And this is cool about generative art, sometimes “mistakes” can make for a more interesting output.

Feel free to play some more with this generator, or check out the other examples, or even create your own generator. What’s that? Oh, you’re still wondering about the animate option?

Alright, let’s go back to bot.js and add this to our options object:

  var options = {
        width: 100,
        height: 100,
        colors: ['571014', 'D4292F', 'FC5978', 'FE7B35', 'FBAC00'],
        animate: true
      };

(Make sure to add a comma after colors.)

For the sake of speeding things up, I also changed the size of the image.

Back to our bot’s endpoint–

This particular generator produces GIFs that are too large for Mastodon’s 8MB file size limit, so the quality is a little too low, but you could experiment with the encoder settings and maybe find a way to improve this.

Automating your bot

The final step in this tutorial will be automating our bot. Glitch puts inactive apps (that is, apps that don’t get any outside traffic) to sleep after 5 minutes, so you will have to either periodically refresh your bot’s endpoint URL all day, or, a much more convenient solution, use a site like cron-job.org or uptimerobot.com to do that for you.

Here’s a little guide I wrote for cron-job.org.

If you want to keep your bot running permanently, you will need to sign up for a Glitch account, which I would highly recommend even for other projects, not just bots.

If you get stuck at any point during this tutorial, feel free to join the Botmakers group and someone will be happy to help you out.

Thanks for following along, and have fun making generative art bots!

Stefan

Creator of Botwiki and Botmakers, Botwiki editor and Botmakers community manager.