Building a Twitter Bot with Vapor
Learn how to build a Twitter bot and create your own tweet automation tools with Vapor and Server Side Swift. By Beau Nouvelle.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Building a Twitter Bot with Vapor
20 mins
- Getting Started
- Becoming a Twitter Bot Developer
- Setting Up a Twitter Developer Account
- Your First Twitter App
- Scheduling Tweets With Vapor Queues
- What are Queues?
- The Redis Queue Driver
- Tweet Scheduling
- Interacting With the Twitter API
- API Keys and Secrets
- Managing Tweets
- Twitter OAuth
- Posting a Tweet
- Where to Go From Here?
The saying “Work Smarter, Not Harder” is thrown around a lot these days. You may hear it from managers and salespeople, but did you know that it was an engineer who said it first?
Allen F. Morgenstern was likely thinking about automation when he coined the term in the 1930s. Today, automation in the form of robot vacuums, self-driving cars and digital assistants improve our lives by relieving us of the most tedious and repetitive tasks, freeing up time for more fun activities, like learning Swift!
This tutorial will help you work smarter by teaching you how to automate your Twitter presence like a pro.
You’ll learn how to:
- Set up a Twitter Developer Account.
- Send tweets using the Twitter API.
- Schedule tweets using Vapor queues.
By the end of the tutorial, you’ll have a web app that tweets a Steve Jobs quote to your account once per day.
Getting Started
Download the projects by clicking Download Materials at the top or bottom of the tutorial and unzip it.
The Twitter API requires you to make requests using OAuth1, and the starter project contains all the necessary OAuth code.
Open the project in Xcode by double-clicking Package.swift. Once open, the Swift Package Manager may take some time to pull the dependencies included in the project.
Browse through the folders to familiarize yourself with the project and give it a run to make sure everything compiles.
You’ll see the following output:
[ NOTICE ] Server starting on http://127.0.0.1:8080
Becoming a Twitter Bot Developer
Twitter bots are simple apps that perform tasks on the Twitter platform. They can do many things like post tweets, like tweets and even collect information on Twitter trends.
Companies might use bots to help with customer support, while influencers may use them for scheduling tweets to go out at specific times of the day.
Bots can also listen for events on other platforms and act upon changes, such as posting a tweet when a website publishes a news article.
There’s even a bot that generates moths and gives them made up scientific names, @mothgenerator!
Before you start sending tweets using Twitter’s API, you’ll need to set up your developer account and generate a few security keys.
Setting Up a Twitter Developer Account
Log into your Twitter account in your web browser and go to: https://developer.twitter.com/en/apply-for-access.
Click Apply for a developer account. You’ll start a short setup process during which you’ll need to answer a few questions.
On the first screen, choose Hobbyist ▸ Making a Bot ▸ Get Started.
You’ll need to provide and verify your phone number on the next screen if you haven’t already done so on your Twitter account.
From this point on, the sign-up process is straightforward. How you answer the questions depends on your own preferences and the kind of apps and bots you plan to build. When you finish, you’ll end up at the Developer Portal Dashboard.
Now you can get a little more creative!
Your First Twitter App
In the panel on the left, open Projects & Apps ▸ Overview. Scroll down and click + Create App.
Here’s the most challenging part of the entire tutorial: Coming up with a name for your app!
The name must be unique so it won’t clash with the existing names already on the platform. If you’re out of inspiration, name it QuoteBot with a bunch of random numbers after it.
The next stage takes you through to the Keys & Tokens screen. Copy the API Key and API Key Secret somewhere safe. You’ll need these later.
Keep them secret. Keep them safe.
You’re almost at the final step. Click App Settings at the bottom right of the screen. Scroll down to App Permissions, click Edit and change your apps permissions to Read and Write. Click Save and confirm the change to permissions in the dialog that appears.
Next, click Keys & Tokens. You can find that under your app’s name, next to Settings. If you ever lose your tokens, this is where you’ll go to generate new ones.
At the bottom of this list, you’ll find a section called Access Token and Secret. Click the generate button and save both of those, too.
That’s it! You’re all done with the paperwork!
Scheduling Tweets With Vapor Queues
Before you start this section, it’s important to go through this checklist to ensure you have everything you need:
- Starter Project
- API Key
- API Key Secret
- Access Token
- Access Token Secret
Twitter uses the API Key and API Key Secret to identify your app. Think of them as your app’s username and password. The Access Token and Access Token Secret provide further authentication to let your bot post tweets to your personal account.
Thankfully, you don’t need to know too much about these, as the starter project has done most of the authentication work for you.
What are Queues?
Many web services do a lot more than serve up web pages or respond to API requests. Have you ever wondered how newsletters show up in your inbox on time every week? What about the process that controls sending verification codes or push notifications?
It’s these little workers that make it all happen, and Vapor has them built-in!
You can put jobs into a queue and schedule them to run at specific times or when a certain condition is met. Think of them like little worker bees, waking up to perform a specific task and going back to sleep when they finish.
Of course, this is a simplified explanation. If you’d like to learn more, there’s an excellent tutorial on the subject called Vapor and Job Queues: Getting Started
Your server will use one of these little workers to tweet a quote to your personal account every day at noon.
The Redis Queue Driver
There are two drivers available for working with queues in Vapor: Redis and Fluent. The Fluent driver lets you store your jobs within a database. Because this project doesn’t have a database and all the quotes are only strings in a Swift file, you’ll use the Redis driver.
With the starter project still open in Xcode, navigate to Package.swift. In the first dependencies
array, add:
.package(url: "https://github.com/vapor/queues-redis-driver.git", from: "1.0.0")
Next, add this code to the dependency array in your App
target.
.product(name: "QueuesRedisDriver", package: "queues-redis-driver")
This code adds the QueuesRedisDriver package to the project and sets up a reference to it within the App
target.
Save this file and Swift Package Manager will download and build the Redis driver. If you set everything up correctly, you’ll now see four new packages added to the Package Dependencies list.
Tweet Scheduling
In Vapor, scheduled jobs are objects that conform to ScheduledJob
and configured using run(context: QueueContext)
.
To set up a scheduled job, create a new folder named Jobs inside Sources ▸ App. Then add a new Swift file inside Jobs. Name it SendTweetJob.swift and populate it with:
import Foundation
import Vapor
import Queues
struct SendTweetJob: ScheduledJob {
// 1
func run(context: QueueContext) -> EventLoopFuture<Void> {
// 2
context.logger.info("Posting Scheduled Tweet")
// 3
return context.eventLoop.makeSucceededFuture(())
}
}
There’s not a whole lot going on in this code at the moment, but here’s how it works:
- This method executes when
ScheduledJob
triggers. - Here, you send a log to the console. You’re not sending any tweets yet, but you’ll need this feedback for testing.
- This forces
SendTweetJob
to always succeed, even if a tweet fails to send. Handling errors is beyond the scope of this tutorial. For more details, check out Chapter 4 of Server-Side Swift with Vapor.
Next, open configure.swift and the following import:
import QueuesRedisDriver
To set up job scheduling, add this code inside configure(_ app: Application)
before try routes(app)
:
// 1
try app.queues.use(.redis(url: "redis://127.0.0.1:6379"))
// 2
app.queues.schedule(SendTweetJob())
.everySecond()
// 3
try app.queues.startScheduledJobs()
Here’s a code breakdown:
- You tell Vapor to use Redis to manage its queues.
- You set up a schedule for the
SendTweetJob
created in the previous step. In this case, the job runs every second. When it’s time to start sending tweets, you’ll change this to a daily schedule. - This final step tells Vapor that setup for all queues is complete, and they can start running!
Click the Xcode play button to build and run!
After a short wait, you’ll see the job logging to the console once every second:
[ NOTICE ] Server starting on http://127.0.0.1:8080 [ INFO ] Posting Scheduled Tweet [ INFO ] Posting Scheduled Tweet
With that in place, it’s time to start working with the Twitter API to send some tweets!
Interacting With the Twitter API
It may surprise you to know the official Twitter documentation uses status updates when referring to what is more commonly known as tweeting. Therefore the statuses/update
endpoint is the one you’ll use to tweet!
API Keys and Secrets
Open OAuth.swift and at the top you’ll find four properties relating to Authorization Keys:
let apiKey = "replace with API Key" let apiSecret = "replace with API Key Secret" let accessToken = "replace with Access Token" let accessSecret = "replace with Access Token Secret"
Remember the keys you collected earlier? You’ll need to use them now. If you lose these keys, you can regenerate them in the Twitter Developer Console.
Replace the placeholder strings with your keys and tokens.
Managing Tweets
Now it’s time to build a mechanism to select quotes to tweet.
Inside Sources ▸ App ▸ Quotes, create a new file named QuoteManager.swift and add:
import Foundation
import Vapor
class QuoteManager {
// 1
static let shared = QuoteManager()
// 2
private var quoteBucket = Quotes.steveJobs
// 3
private func nextQuote() -> String {
if quoteBucket.isEmpty {
quoteBucket = Quotes.steveJobs
}
return quoteBucket.removeFirst()
}
// TODO: Add tweetQuote method
}
Here’s a code breakdown:
-
QuoteManager
is a singleton to ensurequoteBucket
isn’t de-initialized between jobs. - It has a list of quotes the job will pull from when it’s time to send a tweet.
- This method removes and returns the first quote stored in
quoteBucket
. When the bucket is empty, it will refill and start the cycle again.
Now, replace // TODO: Add tweetQuote method
with the following:
@discardableResult
// 1
func tweetQuote(with client: Client) -> EventLoopFuture<ClientResponse> {
// 2
let nonce = UUID().uuidString
// 3
let timestamp = String(Int64(Date().timeIntervalSince1970))
// 4
let quote = nextQuote()
// TODO: Add OAuth
}
Here’s a code breakdown:
-
run(context: QueueContext)
from a previous step gives you access to aQueueContext
, which has anapplication.client
that you can pass to this method when running aScheduledJob
. - The
nonce
is a one-time use string. In this case, you use Swift’sUUID
to create it. In practice, you can use anything here, providing it won’t ever clash with any other nonce submitted to Twitter. The nonce protects against people sending duplicate requests. - This tells Twitter when the request was created. Twitter rejects any requests with a timestamp too far in the past.
- This removes and returns the first quote in the bucket, and refills it if it becomes empty.
You’re almost there. Now you need some authentication and then you’ll be ready to tweet :]
Twitter OAuth
Locate // TODO: Add OAuth
and replace it with:
// 1
let signature = OAuth.tweetSignature(nonce: nonce, timestamp: timestamp, quote: quote)
// 2
let headers = OAuth.headers(nonce: nonce, timestamp: timestamp, signature: signature)
// 3
let tweetURI = URI(string: tweetURI.string.appending("?status=\(quote.urlEncodedString())"))
// TODO: post tweet
The first two lines call helper methods on OAuth
. While the code backing these methods isn’t too complex, it’s beyond the scope of this tutorial. If you’d like to know more about how Twitter authenticates, check out the documentation.
Take a look at this code, and you’ll notice:
- It generates the
signature
using thenonce
,timestamp
andquote
. This method is specific to sending POST requests to thestatuses/update
endpoint and is responsible for combining and converting all parameters into a single string. - It applies the
signature
from the previous step to theheaders
. Request headers have a variety of uses including telling the remote server what type of device is making the request, as well as what data types may be present. In this case, all this code does is create an authorization header. - The
tweetURI
has thequote
appended as a URL query. You may also be familiar with adding the content you’re sending to the body of a POST request, but this is how Twitter does things.
You may have noticed that some parameters appear multiple times. Look at the nonce
and you’ll see that it’s used in the creation of the signature
and the oAuthHeaders
. But if the signature
already contains the nonce
why does it also need to go in the header?
It’s in the header so Twitter can be certain that no request tampering occurred between the time it left your server and arrived at theirs. This also explains why the quote
is also part of the signature
.
It’s time to tweet, finally!
Posting a Tweet
Vapor has a few ways to make requests to another service. These are accessible through the client
object.
Find // TODO: post tweet
and replace it with:
return client.post(tweetURI, headers: headers)
This code uses client
to send a POST request to tweetURI
and returns a EventLoopFuture<ClientResponse>
.
You’re now ready to tweet!
To test, replace all the code inside routes.swift with:
import Vapor
func routes(_ app: Application) throws {
app.get { req -> EventLoopFuture<ClientResponse> in
return QuoteManager().tweetQuote(with: req.client)
}
}
Build and run.
With the server running, open a Terminal window and trigger the tweet with the following curl command:
curl http://localhost:8080
Go to your Twitter feed and check that the tweet has been posted!
QuoteManager
singleton it will start life again with a full tweetBucket
and attempt to send the same tweet twice! This, of course, is something that Twitter ignores.
To set up scheduling, open SendTweetJob.swift. Add this line before the return statement in run(context: QueueContext)
:
_ = QuoteManager.shared.tweetQuote(with: context.application.client)
Next, you’ll want to change the time of scheduling. Switch over to configure.swift and swap this code:
app.queues.schedule(SendTweetJob())
.everySecond()
with:
app.queues.schedule(SendTweetJob())
.daily()
.at(.noon)
Congratulations! You now have a Twitter bot that will post new tweets on your behalf every day at around lunchtime!
Where to Go From Here?
Download the final project by clicking Download Materials at the top or bottom of the tutorial.
This tutorial is only a brief look at what you can achieve when building Twitter apps. Take a look around at what others have done for inspiration. You can use Twitter apps to automate your presence on Twitter or create something entirely new!
Take it to the next level by trying some new things such as:
- Adding more quotes. Or tweet something else like daily horoscopes, affirmations or encouragement.
- Building an app that tweets a daily weather forecast or weekly comic strip. Have your server pull data from another server and send it to Twitter!
- Keeping your server running indefinitely. Running your server on your main computer is one thing, but if you want to get serious, check out the deployment chapters in the Server Side Swift with Vapor Book
We hope you enjoyed this tutorial, and if you have any questions or comments, please join the forum discussion below!
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development — plans start at just $19.99/month! Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.
Learn more