Automated Serverside Tweeting Using OAuth

Great, our Foller.me Rundown account (@fmrd) now tweets via OAuth and has our application name and link attached to every tweet. It was indeed pretty simple. After reading the specs of the OAuth protocol I came up with a fairly simple solution. I’m using this open source Twitter OAuth php library by Abraham Williams which is quite good, and I do recommend you try some basic OAuth stuff (with sessions, based on Abraham’s example) before proceeding to automated tweeting.

Okay, let me first breifly explain how OAuth at Twitter is supposed to work (focusing on automated work). Step by step:

  1. You browse to some hidden area (which nobody but you has access to) and initiate the app registration process. At this point, your app should go ask Twitter for a request token and provide you with a link to Twitter authentication (which will contain the received token)
  2. Next, you click on that link which directs you to Twitter, login, click allow and you’ll be redirected back to your application page (not the hidden area!) with the request token attached to the URL.
  3. You copy that token, browse back to your hidden area and initiate the app validation process by providing the token in your request (GET)
  4. Your app will go talk to Twitter again asking them for an access token. It stores that token (in a very safe place) for later use.

That’s pretty much everything. Once you have your access token you can update your status via OAuth as much as you want. Also note that when I mention request token and access token, I mean request token secret and access token secret too. OAuth tokens come in pairs. Token + secret. Yes, it is that simple!

Now let’s get to some coding! Suppse your app is called MyApp and is located at myapp.com. Make sure your hidden area is actually hidden. Choose a nifty directory for your place and make sure you protected it with .htaccess (allow by IP or based on authentication, it’s up to you). Don’t worry, Twitter will not try to access that directory. Twitter (the OAuth Service Provider) doesn’t do anything but give responses to your requests, so block that as strong as possible.

Suppse your hidden server auth place is at myapp.com/hidden/ and there’s an index.php file, your requests would look like this:

myapp.com/hidden/?register

That would mean “initiate the OAuth registration process!”, which will give you the URL to Twitter. And:

myapp.com/hidden/?validate&oauth_token=whatever

Which will get your Twitter OAuth access token and store it somewhere safe. Remember that you’ll have to replace the word “whatever” with the request token provided by Twitter after you authorize.

Let’s look at the php code (omitting the includes and blah blah blah). Just read through the comments, you should be able to understand. Also make sure you got your $consumer_key and $consumer_secret setup in the Twitter OAuth applications settings.

if (isset($_GET["register"]))
{
    // If the "register" parameter is set we create a new TwitterOAuth object
    // and request a token
    $oauth = new TwitterOAuth($consumer_key, $consumer_secret);
    $request = $oauth->getRequestToken();

    $request_token = $request["oauth_token"];
    $request_token_secret = $request["oauth_token_secret"];

    // At this stage you should store the two request tokens somewhere.
    // Database or file, whatever. Just make sure it's safe and nobody can read it!
    // I'll dump mine into files using file_put_content:

    file_put_contents("request_token", $request_token);
    file_put_contents("request_token_secret", $request_token_secret);

    // Generate a request link and output it
    $request_link = $oauth->getAuthorizeURL($request);
    echo "Request here: <a href="" . $request_link . "">" . $request_link . "</a>";
    die();
}
elseif (isset($_GET["validate"]))
{
    // This is the validation part. At this point you should read the stored request
    // tokens. You'll need them to get your access tokens!
    // Mine are located in two files:

    $request_token = file_get_contents("request_token");
    $request_token_secret = file_get_contents("request_token_secret");

    // Initiate a new TwitterOAuth object. This time we provide them with more details:
    // The request token and the request token secret
    $oauth = new TwitterOAuth($consumer_key, $consumer_secret,
        $request_token, $request_token_secret);

    // Ask Twitter for an access token (and an access token secret)
    $request = $oauth->getAccessToken();

    // There we go
    $access_token = $request['oauth_token'];
    $access_token_secret = $request['oauth_token_secret'];

    // Now store the two tokens into another file (or database or whatever):
    file_put_contents("access_token", $access_token);
    file_put_contents("access_token_secret", $access_token_secret);

    // Great! Now we've got the access tokens stored.
    // Let's verify credentials and output the username.
    // Note that this time we're passing TwitterOAuth the access tokens.
    $oauth = new TwitterOAuth($consumer_key, $consumer_secret,
        $access_token, $access_token_secret);

    // Send an API request to verify credentials
    $credentials = $oauth->oAuthRequest(
        "https://twitter.com/account/verify_credentials.xml",
        array(), "GET"
    );

    // Parse the result (assuming you've got simplexml installed)
    $credentials = simplexml_load_string($credentials);

    // And finaly output some text
    echo "Access token saved! Authorized as @" . $credentials->screen_name;
    die();
}

That’s all. It wasn’t difficult, was it? Now that you’ve got your access tokens stored, you can call Twitter API using OAuth at any time! Here’s a brief example:

// Read the access tokens
$access_token = file_get_contents("path/to/access_token");
$access_token_secret = file_get_contents("path/to/access_token_secret");

// Initiate a TwitterOAuth using those access tokens
$oauth = new TwitterOAuth($consumer_key, $consumer_key_secret,
    $access_token, $access_token_secret);

// Post an update to Twitter via your application:
$oauth->OAuthRequest('https://twitter.com/statuses/update.xml',
    array('status' => "Hey! I'm posting via #OAuth!"), 'POST');

Then setup a cron job to access that page URL and you’ll be automatically tweeting! That’s about it.

Now, in conclusion, a few security suggestions. Never, NEVER place your tokens into a publicly visible folder. Deny all HTTP access to them via .htaccess (look at the Files directive) and yes, I’m going to let you finish, but please, PLEASE secure that hidden place we talked about earlier. Yes I’m repeating this and I’ll keep repeating it over and over. If hackers gain access to your hidden place, they’ll be able to swap your account with another one (or just break it). If they get to your access tokens, then they might spam through your account. That’s not very nice, is it? So please, IP based security, password protected, whatever. I close the whole directory down with a “deny from all” rule in .htaccess once I got my access tokens, so if for any reason I’d have to update or change them, I’d have to do more than just browse there.

That’s all. Have a good time with Twitter OAuth and I hope everything goes well. Feel free to post questions or any kind of feedback in the comments section.

About the author

Konstantin Kovshenin

WordPress Core Contributor, ex-Automattician, public speaker and consultant, enjoying life in Moscow. I blog about tech, WordPress and DevOps.

22 comments

  • Hi Konstantin,

    You have done a wonderful job. It helped me a lot to understand the things so easily.

  • I have used the above code and i have stored the access token and secret in the
    database , now in other page when i try to use same access token and access token secret it is giving me "incorrect signature". not sure where i am goin to wrong.

  • yes .. our server time is synched with NTP then also it is giving following array
    in return of the status update.

    Array
    (
    [request] => /statuses/update.xml
    [error] => Incorrect signature
    )

  • Ok, I have made this and it works!

    But what about errors in return values ? How do i catch them to make an user friendly error message or log ?
    What happends if there is a timeout error (perhaps twitter down) ??

  • Dumb question: What exactly is the seven-digit pin that Twitter provides? In other words, once we have that pin, are we sticking it in the URL of our validation page? If so, what variable name are we giving it? I see that you have an "oauth_token=whatever" in your URL, but this seems to be a completely different value (a long, alphanumeric hashed value provided by Twitter). What obvious piece of information am I missing?

  • I can't post the same tweet twice!
    I've setup a cron job to access the page for every hour, but it won't post until I change the tweet!
    how can I make it to tweet the same tweet without problem,
    or how can I make twitter think this is a new tweet not the same as previous one?

    • Essa, actually Twitter doesn't allow you to post duplicate tweets, you might want to change the texts to let them through, or shorten links with different services.

  • Hi,
    i keep getting this error
    Warning: array_merge() [function.array-merge]: Argument #2 is not an array in OAuth.php on line 301

    Any help would be great