A happy story in two parts.
Part the first: How I wrote it
I decided to find some extra guts today and write a plugin for zoia. (If you’re not familiar with the code4lib irc channel, zoia is this charismatic bot who responds to a variety of commands with helpful, or ‘helpful’, things. @forecast gets you an (opinionated) weather report, for example.)
It turns out writing a plugin is not (or need not be) very complicated. But figuring out how was hard, because I couldn’t find a description of the process anywhere. Let’s fix that. Here’s what I did. (With big thanks to Misty De Meo, who told me how to do some of these steps and applied needed permissions. Thanks!)
(Assumes basic Python ability — mostly modifying existing files — and basic github — you’ve authenticated an account and know how to pull/push.)
- Skim the github repository for zoia’s plugins. Figure out how plugins work. OK, so they all have __init__.py, config.py, and plugin.py. Cool. I have no idea what most of the commands or imported libraries mean, but it turns out all of the __init__.py and config.py files are almost exactly the same, so I don’t actually have to know what they mean; I just have to swap in the name of my plugin as needed.
- Spend some quality time with plugin.py examples. Compared the plugin.py files for a few plugins I’ve seen used on channel (that is, I know what they’re supposed to do). Noticed that they all have a similar structure — import the same few things (plus sometimes more as needed), define a class, define a function inside that class which has the same name as the command will have in channel and generally takes the same arguments, et cetera. Some of the plugins elaborate this core structure a lot because they do a ton of things, but they all have the same basic structure.
- Actually write my plugin.py. So I copied the bits the other ones all shared and wrote my unique logic (and help text!) into the one place that differs substantially (the function(s) inside the class). At this point I had __init__.py, config.py, and plugin.py in a new directory together.
- Test, step one: install supybot. I used these instructions. The installation process walks you through the configuration options, and the defaults are sensible. Set yourself up as the owner and use some throwaway irc channel for testing purposes. Make sure runbot/plugins contains the directory with your plugin. (Or figure out how to configure it to look somewhere else, but I never did that.)
- Test, step two: mess with bot in your throwaway channel. Authenticate to bot (/msg <botname> identify <user> <pass>). (Optional, nonrecommended extra step: Blow away bot and reinstall it because you didn’t bother giving the owner a password and it turns out /msg <botname> identify <user> doesn’t work and you don’t know how to just change that one configuration option (the password is hashed in the config file — good bot!) so demolition is easier. Restart bot and authenticate.) @load yourcommand. Attempt to run your command. Discover it doesn’t work, because some of those args you didn’t include in your function because you didn’t see why they were relevant turn out to matter. For something. Add more bits from working plugin.py files. Debug your logic. You know. Hit it with rocks until it works.
- Get write permissions to the code4lib github repo. Ask someone nicely.
- git push the new plugin directory.
- load @fixit — this needs to be done by someone with zoia owner bits, which isn’t me; another ask-nicely problem.
- Cackle with glee. Show off new functionality in channel.
Somewhere after installing supybot I discovered it comes with a supybot-plugin-create wizard which automates a lot of this (except, I presume, the bits with your custom logic), so if you’re starting from scratch you might want to start with installing supybot and see how much of the heavy lifting the wizard does for you. Then again, the reading-a-git-repo way is more educational.
Part the second: The funnest part
The funnest part was that I showed it to people on channel, and a couple people tried it, and then immediately they started remixing it with other bot commands — because you can nest them, you see! Inside of two minutes I saw people do
@who should [fixit]?,
@who should [canuck [fixit]], and
(@scalia puts air quotes around a randomly chosen word in a way that somehow manages to be bitingly sarcastic. @canuck, of course, appends “, eh”.)
In other words, I built a thing and people immediately built things on top of it and made it their thing.
You see? The funnest part.