Twitter API OAuth

On the 5th of March, Twitter is going to retire version 1 of its API. The replacement, version 1.1 is very similar, but with one major difference; every single call must be authenticated.

This means that come March, your existing API calls will break; including simple things like displaying tweets on your site. To fix this, you need to move to the new v1.1 API, and authenticate with Twitter.

Let’s look at how to do this in WordPress, by embedding a list of tweets on your site (Exactly how it is done in the footer here).

Download Finished Script

The Flow

  1. Authenticate with TwitterOAuth.
  2. Fetch the tweets (If our cache has expired).
  3. Did it fail? Use the backup.
  4. Did it succeed? Parse them into an array, then save to the database.
  5. Display.

This post will skip past most of the display and parsing logic. If you want to read up on those, check out the earlier posts: How to Use the Twitter API in WordPress and Add a Backup to Embedded Tweets in WordPress.

1 – Authenticate with TwitterOAuth

TwitterOAuth is a great free library from Abraham Williams. It makes the authentication a snap.

To get going, first download the twitteroauth folder from Github. Place this in your theme folder.

Now, create a new file called tweet-list.php, and paste the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$numTweets      = 3;                // Number of tweets to display.
$name           = 'problogdesign';  // Username to display tweets from.
$excludeReplies = true;             // Leave out @replies
$transName      = 'list-tweets';    // Name of value in database.
$cacheTime      = 5;                // Time in minutes between updates.
 
$backupName = $transName . '-backup';
 
// Do we already have saved tweet data? If not, lets get it.
if(false === ($tweets = get_transient($transName) ) ) :	
 
  // Get the tweets from Twitter.
  include 'twitteroauth/twitteroauth.php';
 
  $connection = new TwitterOAuth(
    'xxxxxxxxxxxxxxxxxxxxxx',   // Consumer key
    'xxxxxxxxxxxxxxxxxxxxxx',   // Consumer secret
    'xxxxxxxxxxxxxxxxxxxxxx',   // Access token
    'xxxxxxxxxxxxxxxxxxxxxx'    // Access token secret
  );

This code holds all of our configuration. The top options are fairly self-explanatory, and control the display on your site.

Let’s skip to the consumer and access keys section. These values are given to you by Twitter. The combination of these ensures to Twitter that you are the user you claim to be, but without giving your password.

This means that a Twitter app should never ask for your password. It also means that if you change your password, you won’t need to update any of your apps.

To find these details, go to https://dev.twitter.com/ and sign in.

Once in, hover on your name in the top right, and click “My Applications,” then “Create a New Application.”

Create a New Application

Enter a unique name, description, and your site’s URL. You can leave the Callback URL empty (It would be used if your app was authenticating each of its users, but our’s will only ever use your account, so we’re going to put the details directly into the script).

Once created, you will be taken to a new screen where you can copy and paste the Consumer Key and Consumer Secret into the script.

Next, click the “Create my Access Token” button. This is a shortcut to authenticate your own account with your application.

Create Twitter Access Token

Finally, copy the new Access Token and Access Token Secret into the script.

Fetch the Tweets

To make a Twitter API call through TwitterOAuth, you use a HTTP verb (GET, POST, or DELETE), specify the API, and then pass in the arguments as an array. You can read the full documentation here.

The API we want to use is GET statuses/user_timeline. Therefore, our code looks as follows:

1
2
3
4
5
6
7
8
9
10
11
12
// If excluding replies, we need to fetch more than requested as the
// total is fetched first, and then replies removed.
$totalToFetch = ($excludeReplies) ? max(50, $numTweets * 3) : $numTweets;
 
$fetchedTweets = $connection->get(
  'statuses/user_timeline',
  array(
    'screen_name'     => $name,
    'count'           => $totalToFetch,
    'exclude_replies' => $excludeReplies
  )
);

If you exclude replies, the total returned from the API will be less than the total your requested. The $totalToFetch logic ensures that we request enough tweets that even after removing the replies, we will have the number we wanted.

Did The Request Fail?

If the request worked, it would have returned with a HTTP status code of 200. We can simply check this, and if it is anything else, use the backed up tweets in our database (We will set this in a minute).

1
2
3
// Did the fetch fail?
if($connection->http_code != 200) :
  $tweets = get_option($backupName); // False if there has never been data saved.

Did the Request Succeed?

If it all went well, we need to pull out the number of tweets we asked for, and parse the data we need from it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
else :
  // Fetch succeeded.
  // Now update the array to store just what we need.
  // (Done here instead of PHP doing this for every page load)
  $limitToDisplay = min($numTweets, count($fetchedTweets));
 
  for($i = 0; $i user->name;
    $permalink = 'http://twitter.com/'. $name .'/status/'. $tweet->id_str;
 
    /* Alternative image sizes method: http://dev.twitter.com/doc/get/users/profile_image/:screen_name */
    $image = $tweet->user->profile_image_url;
 
    // Message. Convert links to real links.
    $pattern = '/http:(\S)+/';
    $replace = '<a href="${0}" target="_blank" rel="nofollow">${0}</a>';
    $text = preg_replace($pattern, $replace, $tweet->text);
 
    // Need to get time in Unix format.
    $time = $tweet->created_at;
    $time = date_parse($time);
    $uTime = mktime($time['hour'], $time['minute'], $time['second'], $time['month'], $time['day'], $time['year']);
 
    // Now make the new array.
    $tweets[] = array(
            'text' => $text,
            'name' => $name,
            'permalink' => $permalink,
            'image' => $image,
            'time' => $uTime
            );
  endfor;

Store the Result

With the data parsed, the last thing is to store it. We will make two copies:

  1. Cached version, which will expire and trigger an update (The transient value).
  2. Permanent version, which will be used if a subsequent request to Twitter fails.
1
2
3
4
5
    // Save our new transient, and update the backup.
    set_transient($transName, $tweets, 60 * $cacheTime);
    update_option($backupName, $tweets);
  endif;
endif;

Display

Now you have a $tweets array with the data successfully parsed into it. All that remains is to display it. We’ll make use of WordPress’ human_time_diff function to give relative times, like 5 minutes ago.

1
2
3
4
5
6
7
8
9
10
11
12
// Now display the tweets.
?>
<ul id="tweets">  
 
    <li>
      <p>
 
        <span class="tweet-time"> ago</span>
      </p>
    </li>
 
</ul>

And that’s it. As before, you can download the complete script here:

Download Finished Script

One final tip is that to test your code, you will want to invalidate your cache (So that the fetch code is run). The easiest way to do this is to add this line right under the config data:

1
delete_transient($transName);

Feel free to comment if you have any issues! Or let me know if there are any other API examples you’d like to see.

Enjoy this post? You should follow me on Twitter!