Continuing the story from Painter Goblin part one, the idea of a Twitter bot started to form earlier this year.
The bare-bones of the Twitter bot were already somewhat in place, I run four bots as it is.
The others send their output exclusively to Twitter via the scheduled tasks that can be run via it.
The neat thing is that it is a bundled library in Python Anywhere and so it doesn’t take any extra work to install it when the code is uploaded to the server.
For those creating a Twitter Bot, it can be run from your regular account (you could run many!), but in most cases, you’ll create a dedicated account. Here I created:
To be able to automate your work Twitter needs to authenticate your code’s access. To do this we first register the app via http://apps.twitter.com/app/new
There are two files the Twitter API by SixOhSix uses to handle authentication with the service. A set of two consumer keys, and a set of two application keys.
With those in place you point the Twitter API to the information and off you go e.g. https://github.com/ross-spencer/painter-goblin/blob/master/twitterpieces.py#L12
Sending a Tweet becomes a two (or (see-below) three-step) process.
- Create a Twitter object and authenticate
- Send the Tweet via your new object
Changes since previous Twitter Bots
The API has changed since the last bot I created. It still has 140 character limits for posts. It also still shortens (or lengthens!) any URL of any length to 22 characters. This needs to be built into a heuristic when dynamically generating text for any Tweet we’re going to make.
A change that has really helped with making a bot is that images no longer count toward the 140 character limit. One less thing to think about! And a bonus for any bots that want to be more visual.
Uploading images is something I haven’t done before. Fortunately the SixOhSix README has a concise section on how to ‘Send images along with your tweets’. Interestingly, to send an image with a Tweet is a three-step process, first it requires authentication, and then the image is uploaded to the Twitter dedicated server, which then returns an image key that is then sent with your text.
# Send images along with your tweets: # - first just read images from the web or from files the regular way: with open("example.png", "rb") as imagefile: imagedata = imagefile.read() # - then upload medias one by one on Twitter's dedicated server # and collect each one's id: t_upload = Twitter(domain='upload.twitter.com', auth=OAuth(token, token_secret, consumer_key, consumer_secret)) id_img1 = t_upload.media.upload(media=imagedata)["media_id_string"] id_img2 = t_upload.media.upload(media=imagedata)["media_id_string"] # - finally send your tweet with the list of media ids: t.statuses.update(status="PTT ★", media_ids=",".join([id_img1, id_img2]))
One issue discovered in testing was that the SixOhSix API version on Python Anywhere was behind that on GitHub – I’ve implemented legacy code to match versions on the server. I’ve also implemented the up-to-date mechanism so as to future-proof the code: https://github.com/ross-spencer/painter-goblin/blob/master/twittergoblin.py#L78
Lessons learned from before…
In creating this new code I wanted to make up for a few shortcomings. There were two design decisions I was able to incorporate, namely:
- The ability to test Tweets with a –notweet flag
- Improved ability to run code manually
The latter is a feature I was particularly keen on. While I like the idea of Painter Goblin as an art project, there are times it is nice to be able to run the process manually on special occasions for others, or at their request. Or just for fun to make new art for yourself.
We’ll see how this progresses in future posts as we get into the visual detail of the project.