Recently, I launched DailyWikiBot, a Python-based mastodon bot which posts a random wikipedia article once a day. And since it's somewhat simpler than the other ones, I thought this would be a good chance to talk about how I did it, in the hope that other people go forth and make bots too.
To be clear, there are a LOT of bot tutorials. Here's a good starting place. I don't really have anything new to add. But I also dislike a lot of tutorials for a couple structural reasons and it feels ethical to make things to help fill that void. Also, it will clarify my own process for me. Finally, writing my own tutorial will help me guilt trip my friends into also making cool and fun bots.
See here or here for the full code on this project (you'll need your own token.secret file).
Step 1 was to come up with an idea for the bot. I have a list of bot ideas (might launch a couple more next week, if I get the time). In this case, I decided I wanted to read more Wikipedia articles and I wanted them to go onto my home feed. So, a bot that posts random Wikipedia articles.
Obviously we need to get a random Wikipedia article. Wikipedia is very tool and API friendly, being mostly worked on by a bunch of nerds. You can find a list of existing tools here and a list of API wrappers by language here. I wanted to work with Python, so I went to the Python section and picked pwiki
. I don't need to do anything complicated or weird, so a simple language is what we want.
pwiki
can be pipped or installed through a GUI package manager in, for example, PyCharm. And, as a bonus, pwiki
already has a random article function. Which makes the following really easy:

Bam! Random article generation, just like that. You could easily change which wiki you sample from just by changing the link. This should work for any wiki based on the standard setup, but I haven't tested it extensively.
"NS" is short for Name Space, which is just specifying the type of page you want. There's a list here. NS=0 means Main Space. When I didn't specify NS, I kept getting talk pages. Admittedly, a random talk page bot could be interesting! There's hilarious stuff buried in some talk pages. But the overwhelming majority of talk pages are boring, so we'll worry about that another day.
The other thing we have to do is a little trickery with generators. See, instead of returning an actual article, pwiki returns a "generator", which is Python for a function you can treat like an object for purposes of iteration. It is more complicated that that and someone probably got mad at me for that explanation. To convert it into an object, we can call __next__()
, which I think I'm technically not supposed to do in good coding practices. Meh. Then we have to get index 0 because it's returning a one element list for whatever reason.
Now, this gives us the article name as a string. We may prefer to convert it to a proper URL. This is really easy:

Really easy. I'm in love with Wikipedia link formatting.
Time to register an account and set it up to bot. You can register an account on your favourite server, but botsin.space is recommended. It is open to all bots and friends of bots who aren't being dicks. Just like this tutorial! It will take them a few hours to a few days to manually activate your account (to cut down on spam), so maybe do this step in advance.
Once you have an account, go into the settings. From the Development menu, create a new application. Give it a catchy name. You don't have to change any of the default settings, they should work fine.

After making it, the application will be listed in the Development menu. Click on it. Do not show anyone the screen that follows. The information there is sufficient to compromise the whole account.

The line you want is the Access Token. Create a text file in the same directory as your Python script and put that access token in there. Traditionally the file is named "token.secret", but you can name it whatever you like. This will let your code authenticate that it is allowed to post to this account.
Alright, last trick! Time to actually make it post. We're gonna use a Python package imaginatively called mastodon
.

Pretty easy right? Create a Mastodon
object and then call status_post
to make a post. There are fancier methods for things like images, videos, polls, and threads. We don't need em, but they do exist and you can read about them here.
If your token.secret is in the same folder as the python script you can just do "token.secret" without specifying a path. However, there is one problem with that, which I'll come to in a second. You will need to switch the api_base_url
if you registered to a different server.
Note that I used a try-catch structure here. This is because I copy pasted this code from a different tutorial. I do not properly know how to use try-catch structures, as PyCharm likes to remind me (it complains about this line).
Beautiful! You can run that whenever you like and get a random wikipedia article posted. It would also be really easy to switch out the steps used to generate message
to post anything you want or can think of. That's left as an exercise to the reader.
Final step in the tutorial (the part that a lot of other tutorials seem to miss): how to use cron to automatically run the script.
Cron is a software that lets you schedule commands to be run at a regular interval. Commands can include Python scripts, making it perfect for our use!
Cron should come installed on any Linux system and by extension, Macs. I have no idea if this works on a Windows machine. If you don't currently have cron installed, god help you. Installing things through the command line always turns into a 3 day process that makes me transcend reality through pure force of rage. I do not recommend. If you go down this road, I cannot help you.
First, you gotta decide which computer your bot is going to run on. I run my bots on a cheap raspberry pi that sits on my desk 24/7. This works out great. Raspberry pis are cheap, can just quietly run, and come with cron via being linux based. If I tried to run it off my laptop, the bot would fail to post the first time I was out doing things. A desktop machine is also a good choice. Slap the script and secret token onto the machine and make a note of the file path.
Let's run a test before we cron it. From the command line / terminal / powershell / whatever the hell you call it, in the directory with the Python script, run "python3 script_name.py". If it posts, then you're good! Most likely, it complained you didn't have a package installed. Ah, but didn't you install the package back when you were working on it in editor? Welcome to virtual environments, the bane of my existence. Basically, Python doesn't want packages to be globally available for reasons I do not understand, so you're supposed to confine them to virtual environments.
The easy solution, which I can get away with because I'm working with a quarantined pi that I can fuck up a little, is to just type "python3 -m pip install package_name" (in our case, "mastodon" and "pwiki"). This will install the packages globally, which is probably fine? Technically, this is considered "bad form" by actual programmers. But I'm here to tell you that programming is fake, computers are just carefully organized sand, and a little chaos is good for you and definitely won't cause problems down the line.
Let's cron. In the command line, hit "crontab -e". This opens the cron file. This is a list of commands you want to run. Your cron tab may come with some comments describing how to use or it may not.
A cron line looks like this:
0 0 * * * command
In our case, our command is python3 script_name.py
0 0 * * * python3 script_name.py
There are 5 numbers (some of which are *s). In order, they are minute, hour, day of month, month, and day of week. The command will run at any time that matches all 5 values and a *
means match all. So the above line would post once a day at midnight. The clocks work on a 24h system and the day of the week wants a three letter code. See here for more. For a daily bot, pick an hour and minute using the first two and leave the rest. For an hourly bot, turn the second number into a star. For a weekly bot, add a day to the last number.
You can also do every xth time unit with */x (ex: every 3 hours is * */3 * * *
). A list of specific times (command separated) or a range of times also works (ex: 15,45 1,2,4,6 * * *
posts at minute 15 and 45 of hours 1, 2, 4, and 6).
So, to get our bot posting daily, we want something like:
0 8 * * * python3 path/to/script_name.py
Which will post once a day at 8 am.
I made one more change there. I added a path to the script name. Cron runs things from inside the cron folder, meaning you can no longer trust it to get the directory right. As such, you have to specify. Remember you can always check the path by typing "pwd"!
That also causes one other issue. We were relying on the assumption of same directory for the script to find the token.secret. You have to specify now, swapping "token.secret" for "path/to/token.secret" if you don't already have it.
And that's it! That should give you a working and posting bot and you can use this template to make basically any bot you want! Have fun and go forth and prosper. Stay awesome, fellow nerds.
Today's cool link of the day is this article on Bloodknife about the Barbie movie. It echoes a number of the sentiments I had after Barbie. Bloodknife are a cool magazine, usually critiquing science fiction and horror through a queer and anticapitalist lens.