Scheduling posts on Mastodon, the hack-y way

I want to do a “24 days of advent” series of posts, and I’d like to post them automatically via Mastodon, so that I don’t forget.

The Mastodon web UI does not have a scheduling function, and so I wanted a simple way of being able to write a series of posts, and have them posted on the right day. Time is less important - for this exercise, I can have the same time for all posts - but I think I’ve come up with something reasonably flexible.

Talking to the Mastodon api

I am using toot to interface with the Mastodon api.

(toot has a switch for --scheduled-at, as of version 0.28.0, but Debian only has 0.27.0 packaged. And, in a way, I kind of prefer my approach…)

To set it up once installed, use toot auth.

Then, you can post using toot post.

So very simple.

Defining the content for toot

I am using a basic bash script to select and post content, with the content held in a text file. The name of the text file determines the date and time at which it gets posted. (There is an inherent limitation here, that I can post only one post per minute. For my needs, that’s fine.)

The naming convention is YYYY-MM-DD-HHMM.

A post to be sent at 23:00 on 27rd November 2022 would be contained in a file named 2022-11-27-2300, located in /home/neil/Desktop/toots/.

The text in the file is what gets posted, and it needs to be shorter than the maximum text length permitted in a post on the instance in question, else it fails. (Perhaps a future tweak, would be to add a check, to keep it automatically short enough.)

Create an additional directory, at /home/neil/Desktop/toots/old_toots/, which is where your old posts get stored.

Selecting and posting the content

The script for selecting and posting the content is at /home/neil/Desktop/toots/scheduled_toot.sh:

#!/bin/bash

TOOTSDIR=/home/neil/toots/
FILENAME=$(/usr/bin/date +%Y-%m-%d-%H%M)
FILE=$TOOTSDIR$FILENAME
OLDTOOTSPATH=/home/neil/toots/old_toots/


if [ -f "$FILE" ]; 
then

TOOTCONTENT=$(/usr/bin/cat "$FILE")

/home/neil/toot_venv/bin/toot post "$TOOTCONTENT"

/usr/bin/mv "$FILE" "$OLDTOOTSPATH"

fi

And make it executable: chmod 700 /home/neil/Desktop/toots/scheduled_toot.sh

Note that there are very few checks here. If the content of the file is too long, or somehow invalid, the script does not handle it, and will probably fail silently (at best).

cron for scheduling

I have a simple cron job, which runs the script once a minute:

* * * * * /home/neil/Desktop/toots/scheduled_toot.sh

I don’t think this will cause undue load, but we’ll have to see.

Update: keeping the post within the instance character length

Update 2024-02-22: consider this for information only; I’ve never used this

Assuming the maximum length of a post is 500 chars, this version will trim down the content to that length. But better to write it properly in the first place.

#!/bin/bash

PATH=/home/neil/Desktop/toots/
FILENAME=`/usr/bin/date +%Y-%m-%d-%H%M`
FILE=$PATH$FILENAME
OLDTOOTSPATH=/home/pi/toots/old_toots/
OLDTOOTSFILE=$OLDTOOTSPATH$FILENAME

if [ -f "$FILE" ]; 
then

TOOTCONTENT=$(/usr/bin/cat $FILE)

CONTENTLENGTH=${#TOOTCONTENT}

if (( $CONTENTLENGTH > 500 )); then

CHARSTOREMOVE=$((CONTENTLENGTH-500))

TOOTCONTENT=${TOOTCONTENT::-CHARSTOREMOVE}

fi

/usr/bin/toot post "$TOOTCONTENT"

/usr/bin/mv $FILE $OLDTOOTSPATH


fi