Tweets to WordPress Plugin

There are quite a few plugins out there and this post is not about using them, but rather about creating your own. In this tutorial (which will be divided into several parts) we’ll cover the fundamentals of the WordPress Cron (task scheduling) engine, we’ll query the Twitter API every once in a while to gather new tweets, and we’ll publish those tweets as status posts in WordPress.

What You Need to Know

The code is quite easy to follow but before you dive in, make sure you’re familiar with WordPress actions and filters, the general concept of writing a WordPress plugin and have some experience with the Options API. I’m assuming that you have your plugin header (the top-most commented section) ready and the plugin itself activated.

Understanding the WordPress Cron

Hopefully you heard the term cron before, perhaps somewhere in the Linux world. Cron is basically a task scheduler, a program that periodically carries out jobs (so-called cron jobs). WordPress ships with it’s very own Cron API that allows scheduling events and carrying out tasks “in the future”. This is how scheduled posts in WordPress work as well as things like pings and checking for updates.

Before scheduling your own events, make sure you install a very handy plugin called Core Control which comes equipped with a Cron module, very neat for debugging your scheduled tasks.

Tweets to Posts: Core Control

The functions that we’re going to use for task scheduling today are wp_schedule_event and wp_next_scheduled. The former creates a new task while the latter makes sure that the task is not re-created if it already exists. So without any further ado, let’s take a look at our first code snippet:

function my_create_schedule() {
    if ( ! wp_next_scheduled( 'my_tweets_to_posts' ) ) {
        wp_schedule_event( time(), 'hourly', 'my_tweets_to_posts' );
    }
}
add_action( 'init', 'my_create_schedule' );

Go ahead and add that to your plugin file, it simply registers an event called my_tweets_to_posts which is fired every hour, and yes, that will work without any further functions and this is the most tricky part in cron jobs.

You see, my_tweets_to_posts is not a function name, it’s an action which is carried out every hour. Remember I said you should be familiar with actions in WordPress? So basically every hour, WordPress will do this:

do_action( 'my_tweets_to_posts' );

So if there aren’t any functions attached to the my_tweets_to_posts action, then nothing will be done. Make sure this is clear enough before we go on.

Attaching a Function to a WordPress Cron Task

Here is where the real thing happens. It’s quite obvious if you understood the action thing:

function my_fetch_tweets() {
    // This is carried out every hour
}
add_action( 'my_tweets_to_posts', 'my_fetch_tweets' );

That’s all there is to adding a cron job. The real code goes inside that function where the comment is and as you can see the function itself is then attached to the my_tweets_to_posts action which will be fired by the task scheduler. Now before we get into creating our tweets, just in case things go wrong with these schedules, you can always use the wp_clear_scheduled_hook function right after wp_schedule_event, which will clear your cron entry. Again, use the Core Control plugin to debug the whole thing.

Fetching the Tweets

We’ll use the Twitter Search API to look for tweets we’d like to publish on our website. It’s quite flexible since it accepts different goodies in search queries like “from:username” that looks for tweets from a specific user or “filter:links” that looks for tweets that contain links.

We’ll use the WordPress HTTP API to fire HTTP requests at Twitter which will return results as a JSON object. Hopefully you’ve used json_decode in your projects before.

In order to avoid publishing duplicate tweets, we’ll keep a max_id number that would represent the last tweet that we have published and we’ll use that as the since_id argument when querying the Twitter API. We’ll store the value in our options table using update_option.

So in your my_fetch_tweets function implementation, let’s start by adding the following:

$query = "from:themefm";
$max_id = get_option( 'max_tweet_id', 0 );
$author = get_user_by( 'email', 'user@example.org' );

$response = wp_remote_get( 'http://search.twitter.com/search.json?q=' . urlencode( $query ) . '&result_type=recent&rpp=10&since_id=' . $max_id );

So we have set our search query, retrieved the max_id value from the database which won’t exist at first, so it will fall back to 0. We also need to get a user object that would be the author of our tweets. Note that the “current user” won’t do since there’s no guarantee of when cron jobs are fired. This is why we use get_user_by to retrieve a specific user by their e-mail address (or you can use login if you like to).

Finally, an HTTP request is fired using the wp_remote_get function. Note how I formatted the URL string which contains our query, sets the result_type to recent so that our recent tweets are retrieved. We set rpp (results per page) to 10 and specify our $max_id as the since_id. Don’t confuse this with Twitter’s max_id string which would result in tweets only before that ID instead of only after.

The result of the query is stored in our $response object. Next, we should check that response object for errors and if everything’s okay, decode the result, like this:

if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
    $response = json_decode( wp_remote_retrieve_body( $response ) );

    if ( ! empty( $response->results ) ) {
        $max_id = $response->max_id_str;
        update_option( 'max_tweet_id', $max_id );
    }

    // Loop through the tweets and publish them
}

I’m sure you’re familiar with WP_Error which is returned should our GET request fail. We also make sure that our response code is 200 (meaning OK in HTTP language). So if things go well, we use JSON to decode our response body and look at it’s results array. If that’s not empty, we get the max_id that Twitter gave us and store it in our options table for use during the next request.

This is an interesting place to debug but unfortunately WordPress cron jobs don’t return or output any values, they’re executed totally behind the scenes. Luckily though, being familiar with the action API, we know that we can explicitly call do_action somewhere during init and use print_r to inspect our variables. The $response variable is a good place to start with :)

Publishing Our Tweets

Perhaps the most difficult part of all but only due to the date voodoo, since Twitter dates come in one format while WordPress expects them in a different one. Right where we left the comment in our previous snippet, let’s run a foreach loop:

foreach ( $response->results as $tweet ) {
    $gmt_date = date( 'Y-m-d H:i:s', strtotime( $tweet->created_at ) );

    $post = array(
        'post_content' => $tweet->text,
        'post_status' => 'publish',
        'post_date_gmt' => $gmt_date,
        'post_date' => get_date_from_gmt( $gmt_date ),
        'post_author' => $author->ID
    );

    $post_id = wp_insert_post( $post );
    set_post_format( $post_id , 'status' );
}

So as I said, Twitter gives out the tweet creation date in a long but human readable format, while WordPress is expecting MySQL-style dates. This is why we use PHP’s strtotime function to parse Twitter’s date and transform it into one compatible with WordPress.

Note that that’s the date in GMT, so we further manipulate that with a WordPress function called get_date_from_gmt which does exactly what it says — gets a date from the GMT date for whatever timezone is set in the WordPress settings. We use both dates in post_date and post_date_gmt so our WordPress posts are dated the same time the tweets were published.

The rest is quite simple, we set the states and post content, we set the post author and voila! Our post is published with wp_insert_post which returns a $post_id that we use to set the post format to status. Hopefully your theme supports the status post format and you note the difference. If not, try Twenty Eleven ;)

Tweets to Posts with Twenty Eleven

Conclusion

That’s about it for our first part. Of course there are a lot of improvements that could be made to the plugin and we’ll talk about some of them in the next part of this tutorial. If you didn’t manage to get it working, feel free to download the full source of the plugin and compare the two:

Download Source Code

Thank you for reading and hope you enjoyed it. Feel free to ask a question or comment in our form below and stay tuned for part 2!

Oh wait! There’s More! Writing a Tweets to WordPress Posts Plugin (Part 2)