7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Code
  2. Twitter API

Building With the Twitter API: Tweet Storms

Scroll to top
Read Time: 12 mins
This post is part of a series called Building With the Twitter API.
Building With the Twitter API: Using Real-Time Streams
Building With the Twitter API: Repeating Tweets From a Group
Final product imageFinal product imageFinal product image
What You'll Be Creating

In April, investor and Netscape founder Marc Andreessen began expanding on the natural 140 character limits of Twitter by publishing his thoughts in sequences of tweets, which some have dubbed tweet storms (entrepreneur Yvo Schaap compiled these on his website). 

It didn't take long before BuzzFeed (the listicle upstart that must be stopped) rose up against this practice: Why Twitter’s Newest Tweetstorm™ Trend Must Be Stopped. Personally, I'm probably for anything BuzzFeed is against.

A few services arose to make it easier for mere mortals like ourselves to publish tweet storms but they seemed a bit unreliable and inconsistent. I decided to build the feature myself and I think there's value in doing this with your own app.

In this tutorial, I'll walk you through building a tweet storm feature of your own using the Twitter API. This is a continuation of my series of Twitter API tutorials on Tuts+; you can find a link to all of them on my author page.

Tweet Storm Feature Requirements

First, let's decide what we need our TweetStorm feature to accomplish. 

  • Create a group of tweets.
  • Number them in sequence.
  • Publish them in sequential order to Twitter.
  • Provide a public web page allowing people to read them together.
  • Publish the link to this page in a final tweet.

The results should look something like this:

A five step tweet storm with a final public linkA five step tweet storm with a final public linkA five step tweet storm with a final public link

I'll assume that you're familiar with my earlier Birdcage tutorial and already have code that authenticates your account via OAuth with the Twitter API.

The Database Model

Birdcage uses a Status table for tweets. First, we'll extend this table with a Yii ActiveRecord migration to include fields for the published tweet_id and the tweet storm numerical sequence. 

Extending our existing database model is quite easy with Yii's ActiveRecord migrations:

Here's the migration code:

We'll use the tweet_ids to publicly display the entire tweet storm on a web page after publication. The numerical sequence will determine the order of status tweets in our storm.

Next, we need to create a table for a container of status tweets, in essence a container for the tweet storm. I'm going to use the term Group, because we will reuse it for another grouping feature in a follow up tutorial, recurring tweets from within a group. Visit my author page to see when it's out or follow me on Twitter @reifman.

 Let's create a new migration to create the Group table:

The code below builds the schema. Note the foreign key relation to link the tweet storm to a specific Twitter account:

We'll also build a relational table called GroupStatus which tracks the Status tweets within each Group:

To publicly display the tweet storm on a web page, we actually need another table to cache the HTML code by twitter_id from Twitter's Oembed API method:

Building the Code

The Group Controller and Models

Next, we'll use Yii's scaffolding code generator, Gii, to build the model, controllers and CRUD. On my local environment, I visit http://localhost:8888/twitter/app/gii to access Gii. First, I create the model:

Yii Model GeneratorYii Model GeneratorYii Model Generator

Then, I user the Bootstrap CRUD generator:

Bootstrap GeneratorBootstrap GeneratorBootstrap Generator

We'll also use Gii to create default models for the GroupStatus and Embed tables. They don't need controllers and views.

In the navigation bar view (/app/protected/views/layouts/main.php), I'll add an option in my Compose menu to Group Tweets:

The Group Tweets Management page looks like this:

Manage Groups of Tweet StormsManage Groups of Tweet StormsManage Groups of Tweet Storms

Clicking the leftmost icon within each row opens up a group for adding tweets to and sequencing them.

Clicking the add a group menu link will bring up a form that lets you name the tweet storm and choose a Twitter account for it:

Create a Group for a Tweet StormCreate a Group for a Tweet StormCreate a Group for a Tweet Storm

We need to extend the default create behavior to complete the model. I'm reusing my Slugify method from Geogram to create a URL-like slug from the name. Add this to Group.php:

Here's the modified actionCreate in GroupController.php:

Adding Tweets to the Storm

You then add status tweets for your storm and select the numerical sequence with which they should appear:

Compose a status tweet for a tweet stormCompose a status tweet for a tweet stormCompose a status tweet for a tweet storm

We use a derivative form of the status compose form from Birdcage:

Here is the _groupform.php view file:

Here's the getSequence method the form uses, from Status.php:

Status tweets within groups are four characters shorter than 140 to allow for the insertion of sequence numbering.

As you add status tweets to your group, the Manage Group page will look something like this:

Group view for the tweet storm statusesGroup view for the tweet storm statusesGroup view for the tweet storm statuses

Future enhancements might include move up/down sequence controls for the status items as well as some auto-numbering when you add new tweets.

Publishing the Storm

While you can just publish the tweets in sequence, it's helpful to manage this in a background process for robustness, in case there are failures midway through.

Since many Twitter API functions require cursoring or paging, I've already built a background process model into my advanced framework, Birdhouse. I'll show you the basics of adding tweet storm publishing to your application.

When you click Publish storm, we create an action to manage this process in the background:

Then, the normal cron background tasks manage the Action table and will call Action::model()->publishStorm:

This in turn calls the Group model's publishStormItems:

The ActiveRecord query we use to find the status tweets in a group that are unpublished is as follows:

This query uses scopes which are defined as follows in the Status model:

As we loop through each status that needs to be tweeted, we add a prefix for the sequence number e.g. "1. My first tweet is ...":

When a status is posted, the stage is incremented. Future enhancements could include allowing tweet storms to be reposted multiple times. Currently, we just allow one posting (you're welcome, Buzzfeed).

If all of the tweets have been successfully posted, we post a final tweet with a link to the tweet storm:

Here's what a Tweet Storm looks like when published:

Another example of tweet storm in my streamAnother example of tweet storm in my streamAnother example of tweet storm in my stream

Viewing the Storm on the Web

So, while we could display tweet storms publicly on the web in text form like Yvo Schaap, I thought it would be better to use Twitter embeddings that the user can interact with e.g. follow, reply, retweet et al.

Tweet storm shown publicly on the web with OEmbed HTMLTweet storm shown publicly on the web with OEmbed HTMLTweet storm shown publicly on the web with OEmbed HTML

Initially, I thought I might be able to use static HTML code and just replace the twitter_id in the view, but Twitter prefers you make an OEmbed call and cache the HTML for each tweet. I created the Embed table above to do this.

So, first, let's create a route in Yii's UrlManager so our app's path can redirect to view tweetstorms by the URL-friendly slug. In /app/protected/config/main.php, add the storm slug redirect below. That will redirect queries to http://yourdomain/storm/my-thoughts-on-twitters-api to the Group controller's lookup action with my-thoughts-on-twitters-api as the parameter:

Using Yii's controller access filters, let's make it so any public visitor can view storms but CRUD actions are only visible to authenticated users. Modify the accessRules in GroupController.php as follows:

When a request arrives for http://yourdomain.com/storm/your-storm-name, it routes to the Group controller lookup action:

The fetchEmbeds method looks first in our database for a cached copy and then outwardly to the Twitter API to fetch the HTML. The fetchEmbeds method builds an array of HTML tweets:

It uses the Embed model's fetch method:

It only initiates the OAuth connection to Twitter if there is at least one tweet_id that needs to be fetched, and it does so only one time for performance reasons.

In Closing

I hope you found this tweet storm tutorial useful. It was definitely a fun feature to build. Please feel free to post corrections, questions or comments below. I do try to keep up with the Tuts+ comment threads. You can also reach me on Twitter @reifman or email me directly.

You can find the initial Twitter API tutorial for Birdcage here, and a link to all of my Twitter API tutorials on my Tuts+ author page as they are published. Birdcage offers a free and open source Github repository for getting started with the basic Twitter API features.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.