Twitter 1.1 API and cURL

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Pazuzu156
Forum Contributor
Posts: 241
Joined: Sat Nov 20, 2010 9:00 pm
Location: GA, USA
Contact:

Twitter 1.1 API and cURL

Post by Pazuzu156 »

The title says it all. I'm having issues using cURL and PHP to obtain twitter posts using the 1.1 API and OAuth. Back when 1.0 was functional, I used that all the time. Now it's dying tonight, and I'm doing what I can to learn 1.1 and OAuth in the process. What I did was do a lot of Googling, and the best thing I came up with was using this example:

Code: Select all

<?php
function buildBaseString($baseURI, $method, $params) {
	$r = array();
	ksort($params);
	foreach($params as $key=>$value) {
		$r[] = "$key=" . rawurlencode($value);
	}
	return $method . "&" . rawurlencode($baseURI) . "&" . rawurlencode(implode('&', $r));
}

function buildAutorizationHeader($oauth) {
	$r = 'Authorization: OAuth ';
	$values = array();
	foreach($oauth as $key=>$value)
		$values[] = "$key=\"" . rawurlencode($value) . "\"";
	$r .= implode(', ', $values);
	return $r;
}

$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

$oauth_access_token 		= "ACCESS_TOKEN";
$oauth_access_token_secret 	= "ACCESS_TOKEN_SECRET";
$consumer_key 				= "CONSUMER_KEY";
$consumer_key_secret 		= "CONSUMER_KEY_SECRET";

$oauth = array( 'oauth_consumer_key' 		=> $consumer_key,
				'oauth_nonce' 				=> time(),
				'oauth_signature_method' 	=> 'HMAC-SHA1',
				'oauth_token' 				=> $oauth_access_token,
				'oauth_timestamp' 			=> time(),
				'oauth_version' 			=> '1.0');

$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;

$header = array(buildAutorizationHeader($oauth), 'Except:');
$options = array(CURLOPT_HTTPHEADER	=> $header,
				 CURLOPT_HEADER => false,
				 CURLOPT_URL => $url,
				 CURLOPT_RETURNTRANSFER => true,
				 CURLOPT_SSL_VERIFYPEER => false);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);

print_r($twitter_data);
?>
However, all of this returns a blank screen. So naturally, I used the OAuth tool on the twitter dev site, generated a request and sent it though cURL in Terminal, SUCCESS! I generate one using this method as it seems to work for everyone, FAIL! It cannot be authenticated. I've been at this all day, and I'm getting a stress headache because I cannot figure this thing out. Any suggestions or something to help me get this to actually do something? :banghead:
- Kaleb Klein
------------------------------------
Web Developer | Software Developer
https://kalebklein.com
PGP Key: https://keybase.io/pazuzu156
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Twitter 1.1 API and cURL

Post by requinix »

Make sure you have display_errors on and error_reporting set to include everything in case there are error messages being raised that you can't see.
Then check values of variables. How does $options look? Does $json contain anything?
User avatar
Pazuzu156
Forum Contributor
Posts: 241
Joined: Sat Nov 20, 2010 9:00 pm
Location: GA, USA
Contact:

Re: Twitter 1.1 API and cURL

Post by Pazuzu156 »

My options look like this when i print the array:

Array
(
[10023] => Array
(
[0] => Authorization: OAuth oauth_consumer_key="CONSUMER_KEY", oauth_nonce="hex stuff", oauth_signature_method="HMAC-SHA1", oauth_token="OAUTH_ACCESS_TOKEN", oauth_timestamp="1362450838", oauth_version="1.0", oauth_signature="base64 stuff"
[1] => Except:
)

[42] => 0
[10002] => https://api.twitter.com/1.1/statuses/user_timeline.json
[19913] => 1
[64] => 0
)

$json is completely empty, but I did pass the headers through a curl command exactly similar to the one when you run the OAuth tool on twitter, however I get this:

{"errors":[{"message":"Could not authenticate you","code":32}]}

EDIT:
I played around with it some, and using the home_timeline.json i was able to get the returned text. Exactly what I needed, sorta...I need info from user_timeline.json

What I did after I got it working was I added queries to the url, and yet again, thrown with the same error as above. This is how I added it:

Code: Select all

$url = "http://api.twitter.com/1.1/statuses/home_timeline.json";
$query = array( 'count' => 5 );

$oauth_access_token = "OAUTH_ACCESS_TOKEN";
$oauth_access_token_secret = "OAUTH_ACCESS_TOKEN_SECRET";
$consumer_key = "CONSUMER_KEY";
$consumer_secret = "CONSUMER_SECRET";

$oauth = array( 'oauth_consumer_key' => $consumer_key,
                'oauth_nonce' => time(),
                'oauth_signature_method' => 'HMAC-SHA1',
                'oauth_token' => $oauth_access_token,
                'oauth_timestamp' => time(),
                'oauth_version' => '1.0');
$base_params = empty($query) ? $oauth : array_merge($query,$oauth);
$url = empty($query) ? $url : $url . "?" . http_build_query($query);

$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
Something that looks like this: https://api.twitter.com/1.1/statuses/us ... twitterapi

OAuth seems to hate this and throws me the error when I do it.

I'm quickly beginning to think this is more trouble than it's really worth.. :banghead:
Last edited by requinix on Mon Mar 04, 2013 9:31 pm, edited 2 times in total.
Reason: removing potentially sensitive information
- Kaleb Klein
------------------------------------
Web Developer | Software Developer
https://kalebklein.com
PGP Key: https://keybase.io/pazuzu156
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Twitter 1.1 API and cURL

Post by requinix »

I totally edited out stuff that didn't need to be. Sorry about that.

So you have the home_timeline version working fine. What's the difference between the code for that and the code for the user_timeline version? I don't know the API but could there be any kind of setup required on the Twitter end of things (ie, is there any kind of limitation on your API keys)?
User avatar
Pazuzu156
Forum Contributor
Posts: 241
Joined: Sat Nov 20, 2010 9:00 pm
Location: GA, USA
Contact:

Re: Twitter 1.1 API and cURL

Post by Pazuzu156 »

The only limitation I'm aware of is the number of requestors toy can make peer hour which is like 3,200 or something like that. I honestly don't know the difference, everyone else cam get this working for them and can get info from get queries. It works fine for me until I add those to my URL.
- Kaleb Klein
------------------------------------
Web Developer | Software Developer
https://kalebklein.com
PGP Key: https://keybase.io/pazuzu156
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Twitter 1.1 API and cURL

Post by requinix »

Finally found the documentation I wanted.

Code: Select all

$base_info = buildBaseString($url, 'GET', $oauth);
$oauth was the old key/value pair. You need to pass the modified one in $base_params.
User avatar
Pazuzu156
Forum Contributor
Posts: 241
Joined: Sat Nov 20, 2010 9:00 pm
Location: GA, USA
Contact:

Re: Twitter 1.1 API and cURL

Post by Pazuzu156 »

I did that, I even went into manually adding the url in the $options under CURLOPT_URL, and still get that error.
- Kaleb Klein
------------------------------------
Web Developer | Software Developer
https://kalebklein.com
PGP Key: https://keybase.io/pazuzu156
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Twitter 1.1 API and cURL

Post by requinix »

It's not for the URL.

So with

Code: Select all

$base_info = buildBaseString($url, 'GET', $base_params);
you still have the problem? Have you looked through that link to make sure you're using the additional query string information (ie, the count) correctly in the signature?
User avatar
Pazuzu156
Forum Contributor
Posts: 241
Joined: Sat Nov 20, 2010 9:00 pm
Location: GA, USA
Contact:

Re: Twitter 1.1 API and cURL

Post by Pazuzu156 »

Yes, I have. I've read through it 5 times, as well as worked with curl. The authorization works correctly when I run a curl command through the console. However, I'm passing the queries with --data and since there isn't a way to do that in PHP I add the query at the end of $url instead. However, the oauth signature is generated with the queries in mind.
- Kaleb Klein
------------------------------------
Web Developer | Software Developer
https://kalebklein.com
PGP Key: https://keybase.io/pazuzu156
Post Reply