loading...
Botwiki

Introduction to Mastodon bots

stefan profile image Stefan Bohacek ・8 min read

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.

If you haven't heard about Mastodon before, it's a social networking software that lets anyone host their own social network site. (There are similar projects, for example GNU social). All of these sites can be connected in what is known as the fediverse. (You can head to Wikipedia for a more detailed description.)

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.

Making your first Mastodon bot

Setting up a new account for your bot is a breeze. First, you need to choose which Mastodon instance you want your bot to be on. I recommend botsin.space, which was created specifically to run friendly bots.

Make an account for your bot

After you confirm your email, click the “Edit profile” link under your username and check off “This is a bot account”.

This is a bot

After this, go to the Preferences page (the “cog” icon) and then click Development.

Preferences

Development

Now click the New Application button. Name your application, keep the settings the way they are, and click the Submit button at the bottom of the page.

Now you can click your application’s name to reveal the access token for your bot. If you only see your API key, use this tool to generate your token.

New application

Your new bot

And you’re done. Now for the fun part. For this tutorial I'm going to use my generative-art-bot starter project on Glitch. You don't need to sign up for an account right now, Glitch lets you create temporary projects for you to test things out.

First, click the Remix button.

Remix the project

Next, update your .env file with your 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 later in 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.

Log button

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

Show button

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

Log

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

Our art!

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.

Almost

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--

Animated

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.

I'm going to use cron-job.org to show you how to set this up.

Once you sign up for an account, head to the "Cronjobs" section and add a new cronjob.

Add new cronjob
Add new cronjob

Click "User defined" under "Schedule". Here, select all the options under Days of months, Days of week, Months. Under Minutes, select 0. And under Hour, select on which hour your bot will post.

For example, if you want to post every 6 hours, select the options 0, 6, 12, and 18.

Time settings

Hit the "Create cronjob" button at the bottom of the page, and you're all set!

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!

Posted on by:

Botwiki

Cataloging the world of creative bots, clumsy AI, and machine ethics.

Discussion

markdown guide