Making a Mastodon bot that posts random images

Share images from a Google Drive folder using Python and Pipedream.

📅 4 months ago | Updated 2 months ago

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

In this tutorial, I will walk you through creating a Mastodon bot that shares random images from a folder and attaches a description to them.

Familiarity with Python will be helpful, but not entirely necessary, as the syntax is pretty beginner-friendly.

We will be using Pipedream to run our code, and Google Drive to host our images, both of which require a free account.

First, go to your Google Drive and create a folder for your project. In this folder, create another folder for all your images, and a blank spreadsheet.

Screenshot from Google Drive showing our folder structure.

Open your spreadsheet and add the following columns:

  • image_url
  • text
  • alt_text

Next, upload your images to your image folder. Then, one by one, get a link for each of them via the right-click menu. Make sure that the Anyone with the link option is selected under General access.

Screenshot of the Google Drive interface showing how to get a URL of a an image.
Screenshot of the Google Drive interface showing how to share an image publicly and retrieve its URL.

Put each URL in the image_url column. You can describe the content of each image in the alt_text column, and also fill out the text of the tweet that will share this image in the text column.

Screenshot of a spreadsheet that holds the data for our bot.

Now that we have our images, let’s look at some code that will randomly pick one and tweet it out.

First, create a new account for your bot and get your access token. You will then need to save your token and the instance URL in your Pipedream settings.

MASTODON_INSTANCE="https://botsin.space"
MASTODON_ACCESS_TOKEN="your token here"

A screenshot from Pipedream.io settings page showing a field for input environmental variables.

If you want to make multiple bots, you can differentiate their API keys by adding the bot’s name to each key’s name, for example:

MASTODON_INSTANCE="https://botsin.space"

MASTODON_ACCESS_TOKEN_BOT_1="123-ABCDEFGHIJKLMNOP"
MASTODON_ACCESS_TOKEN_BOT_2="456-IJKLMNOPQRSTUVWX"
MASTODON_ACCESS_TOKEN_BOT_3="789-RSTUVWXYZABCDEFG"

Once your API keys are saved, head over to your workflow dashboard and create a new workflow.

Screenshot of the Pipedream workflows dashboard with the New button highlighted.
Screenshot of  a new workflow trigger being added in Pipedream.

Choose Schedule as a trigger for the bot. For now let’s go with the Custom Interval option to test things out.

Let’s use a short trigger interval, something like 30 seconds. Once we’re done testing, we can go back and change it to something more suitable.

Screenshot of  a new workflow trigger being added in Pipedream.

Next, we’ll add a Python code block that will run every time our scheduler is triggered.

Screenshot of  a new workflow step being added in Pipedream.
Screenshot of  a new code step being added in Pipedream.
Screenshot of  a new workflow step being added in Pipedream with Python code block being edited.

Replace the content of the script block with the following code.

import io
import os
import random
import requests
import urllib.request
import pandas as pd
from mastodon import Mastodon

data_url = "URL OF YOUR SPREADSHEET"
filename = "/tmp/image.png"

def handler(pdm: "pipedream"):
    mastodon = Mastodon(access_token=os.environ.get("MASTODON_ACCESS_TOKEN"), api_base_url=os.environ.get("MASTODON_INSTANCE"), request_timeout=100)

    csv=requests.get(data_url).content
    df=pd.read_csv(io.StringIO(csv.decode('utf-8')))
    data = df.to_dict(orient='records')

    data = [item for item in data
        if ("image_url" in item and type(item["image_url"]) == str and item["image_url"])
        and ("alt_text" in item and type(item["alt_text"]) == str and item["alt_text"])
        and ("text" in item and type(item["text"]) == str and item["text"])
    ]

    item = random.choice(data)
    image_id = item["image_url"].split("/")[5]
    image_url = f"http://drive.google.com/uc?export=view&id={image_id}"

    urllib.request.urlretrieve(image_url, filename)

    media_upload_mastodon = mastodon.media_post(filename)
    mastodon.media_update(media_upload_mastodon, description = item["alt_text"])
    post = mastodon.status_post(item["text"], media_ids = media_upload_mastodon)

    return post

To get the URL of your spreadsheet, head back to your spreadsheet in Google Docs, navigate to File Share Publish to web, and select the Comma-separated values (.csv) format.

This will be the value for your data_url variable.

data_url = "https://docs.google.com/spreadsheets/d/e/1234567890/pub?output=csv"

We’re now ready to test our workflow.

A post from our finished bot, showing one of the images we uploaded to Google Drive.

You can now go back to the scheduler block, set the timer to something like an hour, or whatever your preference is, and then deploy your workflow.

Note that if you don’t use Google Drive to host your images, and are able to use the full URL of your images in the img_url column, you can replace the following code:

    item = random.choice(data)
    image_id = item["image_url"].split("/")[5]
    image_url = f"http://drive.google.com/uc?export=view&id={image_id}"

with this:

    item = random.choice(data)
    image_url = item["image_url"]

If you run into any issues, feel free to reach out! Before you do, a few helpful trouble-shooting tips:

  • Double-check your access token. You can use print(os.environ.get("MASTODON_ACCESS_TOKEN")) in your script to see if the correct value is being used.
  • Make sure all your images and the spreadsheet are public.
  • You can print the response from Mastodon’s API to see if there are any useful error messages.

post = mastodon.status_post(text, media_ids = media_upload_mastodon)
print(post)

Check out the rest of Botwiki for tutorials and examples of creative bots, and join us over at botmakers.org and share what you made!

Until next time!

Stefan

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

Enjoyed the tutorial?

Consider supporting Botwiki!

Latest from the blog

Cheap Bots, Done Quick suspended, this time for good
Cheap Bots, Done Quick suspended, this time for good

So long, and thanks for all the bots.

Twitter shutting down free access to their API on February 9
Twitter shutting down free access to their API on February 9

I keep saying it's an end of an era quite often these days.

How do folks get into creative botmaking?
How do folks get into creative botmaking?

Sharing the stories of our early botmaking days.

Visit the blog

.