Twitter OAuth with PHP and cURL multi
I am maintaining a website that aggregate a large number of Twitter accounts’ tweets. For this purpose we’ve been given one of the accounts with the high API request rate limit – usually it is possible to call the Twitter API’s 150 times every hour. We have a rate limit of 20.000 hourly requests and we use most of them to keep up a near real time picture of the activity of the user base.
Recently Twitter disabled regular basic HTTP authentication supporting only OAuth – which generally is a good thing, In this case we simply read the RSS-version of the user_timeline and OAuth seems overkill for reading a simple public time line.¬†Aaaanyways – we are using PHP with cURL multi and OAuth introduces a bit of extra code. Sure – there are plenty of OAuth API’s and OAuth API’s for Twitter out there, but the specific combination of PHP cURL multi and GET’ing user_timelines required a combination of Google’ing and a bit of guesswork.
Preparations
– First¬†Register your application with Twitter – You’ll need a couple of tokens and secrets from your app-page and from the specific token page.
– If you need to make more than 150 requests per hour, apply for¬†whitelisting here. ¬†It’ll take a while for Twitter to process your request.
– Make sure you have cURL for PHP installed
Specifically preparing the GET connections for cURL presented a challenge – this piece of code did the trick for us:
<?php // $url_array is an array of Twitter RSS-feed URL's that we need to read $mh = curl_multi_init(); foreach($url_array as $i => $item) { // Keys and secrets from http://dev.twitter.com/apps/ $consumer_secret = '<get your own from http://dev.twitter.com/apps/_your_app_id_/>'; $token_secret = '<get your own from http://dev.twitter.com/apps/_your_app_id_/my_token>'; // Build ud an array of OAuth parameters $params = Array(); $params['oauth_consumer_key'] = '<get your own from http://dev.twitter.com/apps/_your_app_id_/>'; $params['oauth_token'] = '<get your own from http://dev.twitter.com/apps/_your_app_id_/my_token>'; $params['oauth_signature_method'] = 'HMAC-SHA1'; $thetime = time(); $params['oauth_timestamp'] = $thetime; $params['oauth_nonce'] = SHA1($thetime); $params['oauth_version'] = '1.0'; // Sort the array alphabetically ksort($params); // Build the paramter string for the GET request $concatenatedParams = ''; foreach($params as $k => $v) { $k = urlencode($k); $v = urlencode($v); $concatenatedParams .= "{$k}={$v}&"; } $unencodedParams = substr($concatenatedParams,0,-1); // URL-encode the parameters for signature use $concatenatedParams = urlencode(substr($concatenatedParams,0,-1)); $signatureBaseString = "GET&".urlencode($item['url'])."&".$concatenatedParams; $params['oauth_signature'] = base64_encode( hash_hmac('sha1', $signatureBaseString, $consumer_secret."&".$token_secret, true) ); // Initiate a new cURL connection and set up it's URL $conn[$i] = curl_init(); curl_setopt($conn[$i], CURLOPT_URL, $item['url'] . '?' . $unencodedParams); curl_setopt($conn[$i], CURLINFO_HEADER_OUT, 1); // Build the HTTP header for the request $curlheader = Array(); $curlheader[]='Content-Type: application/x-www-form-urlencoded'; $curlheader[] = 'Authorization: OAuth'; foreach($params as $ky=>$va) { $curlheader[] = "$ky=$va,\n"; } // Initiate a new cURL connection and assign URL + HTTP header to it $conn[$i] = curl_init($item['url']); curl_setopt($conn[$i], CURLOPT_HTTPHEADER, $curlheader); curl_setopt($conn[$i], CURLOPT_HTTPGET, 1); // Add the connection to the cURL multi handle curl_multi_add_handle ($mh,$conn[$i]); } // Now execute curl_multi_exec on the $mh handle
Add your own comment