This is a short, step by step, tutorial for how to make a twitter bot. The bot I'll create in this tutorial is going to be called "Big Pineapple Guy" and it's purpose will be to comment on my friend's posts with facts about pineapples. I'm going to be making the bot in Go and I'm going to be deploying it onto Heroku so everything will be free. The end result of this will be a bot that comments stuff like this:
I want my bot to have its own Twitter account so step one for all of this is to go to Twitter create a new account for the bot.
Next I need api access to this account. To do that, I need to register as a developer at https://developer.twitter.com. From there, I create a new app and fill it in with basic info about what the bot will be doing.
Once the app is created, I can go in an get the keys and tokens I need.
I'm going to take the keys and tokens that Twitter gave me and put them in a yaml file for now to access them during development.
For the first bit of go code, I'm going to write something to get these credentials from the yaml file. There is a library for parsing yaml that I'll need first.
~$ go mod init // initializing a go module to keep track of dependencies
~$ go get gopkg.in/yaml.v2
Now that I have the library, I can write the basic function to get the credentials. I decided to put it in its own file to keep things clean.
So far the directory for the project should look like this:
Adding a Main
Before programming a main, I have to find a good twitter API client library for go. Fortunately, there seems to be a really go one by a Github user named dghubble.
go get github.com/dghubble/go-twitter/twitter
I want my bot to listen for new tweets from specific twitter handles and run some code whenever that happens. This can be done by listening to twitter event streams. Twitter gives developers the ability to listen for events and filter out unwanted events. The documentation for it is here. In my case, I want to filter by specific twitter handles. The go twitter library I'm using has an example of how to listen to twitter streams (https://developer.twitter.com/en/docs/tweets/filter-realtime/overview). Going off this example, I can create the basic main function for my bot.
The demux is what is used to separate the different message types in the stream. For each message type (i.e. Tweet, DM, Event) I register a callback that is called every time one of those events happens. For now I'm just printing the messages out when I receive them.
Above the main function, I'm going to put a variable that is an array of all the Twitter handles I want to filter.
Unfortunately, I can't filter by just Twitter handles, only Twitter IDs. So I'll need to write something that converts the array of Twitter handles into an array of Twitter IDs.
Using this new ids array, I can filter the stream.
Now that I'm filtering by Twitter IDs and only getting the tweets I want, I can start writing some logic for what do when I receive a new Tweet message.
In the Twitter API, tweets have a ton of field. In the library I'm using, this file has the Tweet struct with all of the available fields. I only want to interact with tweets tweeted directly from my fields, no retweets or replies so that was the first thing I make sure to avoid. With this, I have everything I need to move onto the fun part.
Putting It All Together
Now I get to decide what I want to reply with. I want the reply to be a random pineapple fact so to keep things neat, I'm going to put the list of facts in a new file
Using a random number generator in Go's standard library, I'm going to pick a random item from the list to reply with. It's very important to seed the number generator with the current time because of how I'm going to be deploying it later. This'll just make sure I'm actually using a random number.
Finally, I'm going to add the logic for replying to the tweet.
If everything is set up correctly and there are no bugs, I should be able to build and run this on my own machine.
~$ go build
To test, I added my own personal Twitter account to the array of victims and tweeted some test tweets. With everything working, I can move onto deploying the bot so I don't have to run it on my own computer.
Deploying on Heroku
Before doing anything on Heroku, I'm going to have to make some changes to how I was running the bot. The first is how I'm getting the credentials. I really don't want to check my credentials into git and push them to Github so I'm going to modify the cred.go file to be able to accept credentials from environment variables.
After this modification I can log into my Heroku account and make a new project. In this new project, I'm going to input all of my keys and tokens as environment variables through the web console.
Before actually deploying though, I'm going to add a Procfile to my project folder. This will tell Heroku that my project isn't actually a website and is just a bot.
At this point, my project folder looks like this:
Now I'm ready to push all of my stuff to Github and point Heroku at my Github repo for deployment.
And with that I'm done! I have a Twitter bot written in go running on Heroku. This was a really fun project to make and it was really nice seeing my friends post pictures in our groupchat of a mysterious pineapple account commenting on their posts.