March
31st, 2009
How to quickly integrate with Twitter’s OAuth API using PHP
UPDATE: You can watch me on GitHub, view documentation or fork the project.
A new project I’m working on integrates closely with Twitter. As a result, I become a lot more familiar with OAuth than I care to. Many developers want to be able to speak the OAuth protocol without having to know the fine details. I am deviating from the normal order by starting with an example and explaining it afterwards. If you are interested in using “Sign in with Twitter” then read my other blog post.
A simple example
To follow the example, you’ll need to download these files and have a web server set up. I use my laptop but you can also use a webhost if you’d like. Head over to Twitter and set up an application. The last two fields are important. The callback url will need to redirect to your web server at a location where you will be uploading some files. Assuming you’re going to upload into your web root, the callback url would be something like http://yourdomain.com/confirm.php. You’ll also need to make sure you select “Read & Write” access.
Once you click save, you will be presented with some information. Download the php files for this example and open secret.php. Enter your consumer key and consumer secret in the appropriate areas. Save and upload to your webserver.
Open a browser to your webserver’s start.php file you just uploaded. You’ll see a link to authorize with Twitter. Clicking on that link will take you to Twitter’s site and ask you to log in if you’re not already.

Once you click Allow you’ll be redirected back to your site with a custom greeting pulled straight from Twitter. It doesn’t get much easier than that. From here on out you can use the token and secret provided by Twitter to access the API on behalf of the user who authorized you. Now, the details.
Why use OAuth…the benefits
OAuth is “an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.” What’s that mean? In short, it means that a user of your service can provide you limited access to a third party account of theirs. OAuth is often described as a valet key that your users can give you to access their accounts on other services. For example, a user using Flickr (the service provider) would provide Snapfish (the consumer) with read only access to their Flickr account. This lets Snapfish access photos in the user’s Flickr account so they can order prints.
It’s all in the tokens
How does this happen without asking the user to give up their Flickr password? The flow would start by Snapfish obtaining a consumer key and secret and using them to generate an authorization link to Flickr. Once the user follows the authorization link, they are asked to log in on Flickr’s site. Once logged in they can choose to grant Snapfish access to their Flickr account. Flickr then marks the request token as having been authorized by the user. Snapfish uses the request token to obtain an access token which can be used by to make requests to Flickr on behalf of the user. This diagram may help visualize it easier. C = Consumer, SP = Service Provider

Let’s dive in
I had several goals in writing a PHP client for OAuth and Twitter.
- The two should be decoupled, making it easier to add other OAuth services
- Reuse the asynchronous/non-blocking curl library
- Expose methods which would enable OAuth requests in less than 4 lines of code
Generating a valid OAuth request
It turns out that generating an OAuth request is very simple but debugging it is a pain. Every OAuth request contains certain parameters. These include:
- oauth_consumer_key
- oauth_token
- oauth_nonce
- oauth_timestamp
- oauth_signature method
- oauth_version
- oauth_signature
These can be passed in as GET or POST parameters or in the Authorization header. You’ll most likely be passing in other additional parameters based on the API you’re accessing. I won’t get into the details of what these parameters represent in this blog post but it’s good information to know.
A look inside EpiOAuth
EpiOAuth initializes an instance of the EpiCurl object in its constructor. Since EpiCurl is not included, you’ll want to make sure you’ve made it available ahead of time. There are several methods which you’ll need to know about.
- getAccessToken
- getAuthorizationLink
- getRequestToken
If you reference the diagram above, then these should be self explanatory. There are several other helper methods which act more behind the scenes but play an important role.
- generateSignature
- generateNonce
- httpRequest
- prepareParameters
- signString
These do all the magic to turn an otherwise normal request into a valid OAuth one.
How EpiTwitter extends EpiOAuth
Per my original goal, the Twitter class should contain a very minimal set of functions which call specific endpoints. These methods are self explanatory if you look at them as well. I did, however, want to make it easy to use the class in an asynchronous manner since the underlying http library I was using supports it. This led me to create an EpiTwitterJson. When you make a request you’ll receive an instance of the EpiTwitterJson object without blocking for a response from the Twitter API. You can at any point access individual elements in the response as a member variable. Accessing the member variable with return the value and block if needed.
Wrapping it up
This should help get you up and running. The code provided is very much under construction. I would greatly appreciate contributions to make it better.
If you’re interested in learning more about OAuth then there’s a great set of articles located at http://oauth.net/documentation/getting-started.
Comments are closed on this post. If you find a bug, please open an issue on GitHub.
and living in Sunnyvale, CA.
April 3rd, 2009 at 7:02 pm
Nice. This worked well for me. For some reason I couldn’t get the one from -> http://apiwiki.twitter.com/OAuth-Examples to work.
I am having trouble figuring out how to store the token and then reuse it for further api calls. Any suggestions?
Thanks for all your work so far. Looks great.
April 3rd, 2009 at 8:15 pm
@Adam, If you have a look at confirm.php in the zip file, you’ll see following on line #11.
oauth_token and oauth_token_secret are your access tokens for the account that was authenticated with Twitter - save them. Later, you can use these values by passing them in as the 3rd and 4th parameters to the constructor or use the setToken method as in the example.
Hopefully that helps, let me know if you have any other questions.
April 3rd, 2009 at 8:24 pm
@jaisen
Perfect. That worked. Here’s my code. For anyone that wants to see it …
$user[1] and $user[3] are variables from the database.
April 7th, 2009 at 2:40 am
Hi,
I’ve started to use your lib for a small app I’m building and noticed a bug when trying to do a GET request and another one when the response is an array.
For the first one there’s a simple fix for the other one I did an ugly hack, and would love to discuss with you a better solution. I will really appreciate if you could contact me by my email, or over Gtalk (arikfri).
Thank you for the tutorial and code, btw!
Arik
April 7th, 2009 at 4:44 pm
Hey, just wanted to say thanks for this.
April 8th, 2009 at 1:06 am
Hi,
I want to ask about the PHP version.
Is it working on PHP4?
April 8th, 2009 at 2:09 pm
@wirawan, I haven’t checked if this works with PHP4 but my guess is that it doesn’t. It might be a trivial exercise to make it backwards compatible. I don’t have plans to do that, but if you do then let me know and I’ll include the PHP4 versions along with the current ones.
April 9th, 2009 at 1:07 am
I seem to be having a problem with this… I’m using the same as Adam above:
$user[1] and $user[3] are variables from the database.
It works perfectly for setUserStatus, but returned an error of “This method requires a GET”, on changing it to a get, the calls cannot be authenticated
April 9th, 2009 at 7:41 am
@Daniel, could you show me your getUserInfo() method?
April 9th, 2009 at 8:07 am
@jaisen:
Sure, it’s:
public function getUserInfo() { return new EpiTwitterJson($this->httpRequest('GET', 'http://twitter.com/account/verify_credentials.json')); }It was POST, and then got the error saying it has to be GET and then I got the Authentication error… It could possibly be a problem on Twitter’s end?
April 9th, 2009 at 8:25 am
@Daniel - Twitter just pushed an update to the API that stricts the method for each call, i.e. - GET methods can no longer be sent as POST methods (verify_credentials is a GET method).
Re. why you getting the authentication error - in EpiOAuth.php you need to move lines 59+60 to come before line 49.
April 9th, 2009 at 8:35 am
@Arik:
Thanks a million! It’s working perfectly now :)
April 9th, 2009 at 2:03 pm
@Arik, Thanks! Have you fixed any other bugs? :)
If you can commit the changes to allow access for enumerated arrays as responses then I’ll merge your changes. Else, I might just add what we talked about.
April 9th, 2009 at 2:07 pm
@Jaisen, I planned commiting my fixes earlier today, but then I had to handle some issues with my app (Topify). If I’ll see that I don’t have time for it anytime soon, I will send you my version by mail.
April 9th, 2009 at 5:46 pm
Yup. The ‘verify_credentials’ API call has changed from a POST to a GET.
April 10th, 2009 at 2:15 am
I made some significant updates and included @Arik’s bug fix. Every endpoint should now be supported.
Please see the documentation for usage notes: http://wiki.github.com/jmathai/twitter-async
April 10th, 2009 at 3:42 am
I tried the new code, still no luck :(
April 10th, 2009 at 3:56 am
Great work on this. Very helpful!
I’ve created a quick EpiTwitterXML class since I require XML instead of JSON responses. I’ve added this to the bottom of EpiTwitter.php
class EpiTwitterXML { private $resp; public function __construct($resp) { $this->resp = $resp; } public function __get($name) { return $this->resp->data; } }I also replaced ‘.json’ with ‘.xml’ on line 14 and replaced ‘return new EpiTwitterJson’ with ‘return new EpiTwitterXML’ on line 18
Hope this helps someone. It would be nice to support both XML and JSON in a future version (my solution only replaces JSON with XML)
Have fun.
April 11th, 2009 at 4:36 am
Quick question. I’ve got the code working (authorizing, storing tokens to database, sessions, reusing tokens later etc).
My app lets users view photos (and I’m storing the twitter userId along with the photo). I can’t get the API to pull out the users data (/users/show?user_id=1234) when a user is not authorized. I get invalid session token (because the user isnt authorized).
Simply viewing a photo and calling the users/show method should be available to all users, not only once they’ve authorized.
This isn’t a problem with your code - it’s perfect. I’m just wondering if my best solution is to create some cURL functions to access the REST API (and skip the token/authorization stage) and keep OAuth for authorized requests (posting tweets, login etc)
Any help is appreciated :) Thanks and great work
April 11th, 2009 at 6:11 am
I updated the EpiOAuth and EpiTwitter… And I couldn’t get it to work, so I rolled EpiTwitter back to the old one, changed methods where needed and created new functions to get the friends timeline, repies etc. I’m still using the new EpiOAuth All those work fine, but posting new updates doesn’t work.
It’s the same as it was in the original EpiTwitter:
public function setUserStatus($status = null) { if(empty($status) || strlen($status) > 140) return false; return new EpiTwitterJson($this->httpRequest('POST', 'http://twitter.com/statuses/update.json', array('status' => $status))); }I keep getting “Failed to validate oauth signature or token”. Perhaps EpiOAuth isn’t working right for POST methods..?
April 11th, 2009 at 8:36 am
Looks like a bug with Twitter’s API for POST method endpoints. Several people using various libraries began reporting that POSTs stopped working.
There is an open bug on it here: http://code.google.com/p/twitter-api/issues/detail?id=447
@Daniel, the new version is working fine for me. Could you let me know what errors you were getting for the friends timeline that worked in the old version but not the new?
April 11th, 2009 at 9:51 am
@jaisen:
I got it working now. Before I could just use $friendsTimeline in a foreach, now it has to be $friendsTimeline->response instead.
And, I guess it’s just a matter of sitting back and waiting for the POST bug to be fixed
April 11th, 2009 at 1:09 pm
@Daniel, I definitely suggest using the new version. Once I merge in some changes from Arik you’ll be able to foreach over the returned value and not have to rely on ->response.
April 11th, 2009 at 1:46 pm
Getting this url after changing secret.php data in start.php http://twitter.com/oauth/authorize?oauth_token=
Where is oauth_token missing?
April 11th, 2009 at 2:02 pm
@jaisen:
Yeah, I’m using it now. Thanks for the great work. I’ll keep an eye out for newer versions :)
April 11th, 2009 at 6:24 pm
@Vaibhav, did you remove the {}’s from the key and secret in secret.php?
April 12th, 2009 at 1:02 pm
@wirawan @jaisen My server/host is using PHP 4.4.7 and I’m not able to get this working. Just FYI.
I get:
Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /usr/home/ebar277/public_html/mobile/cgi-bin/oauth/EpiCurl.php on line 4
April 12th, 2009 at 5:50 pm
I updated to the latest version, and when I’m trying to get the authorization URL by using $twitterObj->getAuthorizationLink() I’m getting this error:
Catchable fatal error: Object of class EpiTwitterJson could not be converted to string
I looked at the object, and it’s null:
object(EpiTwitterJson)#3 (1) { ["resp:private"]=> NULL }
Thoughts?
April 12th, 2009 at 7:12 pm
Figured it out - in the updated version you renamed getAuthorizationLink to getAuthorizationUrl.
Thanks for all the great work on this!
April 13th, 2009 at 7:59 am
Has anyone come up with a temporary solution to the problem with POST methods? Or is this entirely in Twitter’s hands?
April 13th, 2009 at 4:26 pm
So the problem with the POST is not twitter, it’s this library. Changing your httpPost method in EpiOAuth to the following should make it work:
final private function httpPost($url, $params = null) { $params['oauth_signature'] = rawurldecode($params['oauth_signature']); $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); //curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); $resp = $this->curl->addCurl($ch); return $resp; }If that doesn’t come through for some reason, the changes are to rawurldecode the $params['oauth_signature'] value and to change the POSTFILEDS to use http_build_query which will use the correct form type.
April 13th, 2009 at 4:59 pm
Thanks Dan,
I tried that and it works perfectly! :)
April 13th, 2009 at 5:34 pm
Anyone have any luck posting non-ascii characters in a status update? I have mb_string functions overridden which usually causes problems with encryption, but I can’t figure out where it’s breaking.
April 13th, 2009 at 5:39 pm
@Dan, thanks for the tip. I had a lot of back and forth with the Twitter devs today. I’m going to commit an update that puts all the OAuth fields in the header of the request. I’ll also have some unit tests to debug this easier in the future.
There was a bug on Twitter’s end that should be pushed tomorrow for non-ascii characters.
http://code.google.com/p/twitter-api/issues/detail?id=433
April 13th, 2009 at 6:28 pm
Here’s the update which puts the OAuth parameters into the header of the request. I’ve also added unit tests for EpiTwitter and EpiOAuth that you can run with phpunit.
http://github.com/jmathai/twitter-async/commit/042c806307357463b1202a24549a530b016def54
This should be completely backwards compatible. Thanks for the tips and helping me find the bug.
April 14th, 2009 at 2:43 pm
Nice work! Thanks, will probably use it for the OAuth implementation in my projects.
April 14th, 2009 at 10:18 pm
@Sam, Just noticed that your comments were flagged as spam (doh!).
If you’ve created support for XML then feel free to fork the repository and send me a pull request. It would be nice to add XML support for everyone to use.
I didn’t quite understand your dilemma. What photos are you referring to?
I’ve published several important updates since your last comment which fixed a bug with POST requests.
April 15th, 2009 at 12:40 am
No problemo dude. Like I said on twitter (@wirah) everythings working perfectly now. I also realised there was actually no need for me to use XML and an XML parser as the json_decode function builds us a nice array from the response already.
One thing that confused me was my line:
$update_status = $twitterObj->post_statusesUpdate(array('status' => $status));wasnt updating the status unless I made a reference to $update_status->response
Works great if I add this line below though:
$temp = $update_status->response;
April 15th, 2009 at 12:51 pm
I’ve trying to use the
get_statusesFriends_timeline(array(’since_id’ => $LastID) and it’s not working it’s returning the a twitter page with “Something is technically wrong.”
I can use OAuth to get get_accountRate_limit_status(); So I’m sure the authentication is right
I can curl it on command line with Basic Auth and it comes back ok using this URL ‘http://twitter.com/statuses/friends_timeline.json?since_id=152565984′
which I cut out of the EpiOAuth httpGet function $url.
Am I missing something here?
April 15th, 2009 at 2:46 pm
@Darwin,
I tracked it down to a bug in the OAuth realm header parameter. It affected all GET requests with a parameter.
I’ve fixed it and committed to GitHub. Thanks for reporting the bug.
April 16th, 2009 at 7:48 am
Thanks for your quick response and fix.
That took care of it.
One more question.
Using $data = $t->get_statusesMentions(array(’since_id’ => $LastID, ‘page’ => $page));
If twitter is down or the authentication fails or there are no new tweets since the last check. What should I be looking for in the returned $data to indicate no new tweets?
April 16th, 2009 at 11:08 am
@Darwin, there are two options you have. You could check the $resp->response->code to make sure it’s 200 (or another if expected). You also have access to the raw response in $response->responseText.
I’m not thrilled about how errors are currently exposed. I’ve thought of several options, one being throwing custom http exceptions if it’s not in the 2xx family. The implementer could then catch and handle them as they see fit. But as Arik had pointed out, not all non-2xx responses are errors.
I’m definitely open for suggestions :). I probably wouldn’t add anything in until I felt really good about it.
April 16th, 2009 at 8:54 pm
Github just released an integrated issue tracker. Feel free to open any bugs you find. http://github.com/jmathai/twitter-async/issues
April 20th, 2009 at 1:52 pm
Is the version for PHP 4.x available yet?
I also get this error now:
Parse error: parse error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /home/content/c/i/t/cityhopper/html/EpiCurl.php on line 4
April 20th, 2009 at 3:37 pm
I am trying to follow along with what you guys are doing but I am a bit confused. I can’t seem to tie in everything together.
What I am trying to do is always authenticate as a particular user and automatically post new status updates.
Would someone be so kind as to make a basic how-to for this script for n00bs like me? :)
April 20th, 2009 at 11:18 pm
So the user will have to click on “Sign in with twitter” everytime they come to my site. So whats the advantage of saving the token and secret token in the database…
April 20th, 2009 at 11:22 pm
@Brant & @Rahul, you need to save the token and secret that you get back from Twitter (->oauth_token and ->oauth_token_secret in confirm.php). Once you save those, you can pass them along with subsequent requests to authenticate as that user. The user does not need to go through the steps of authorizing your application a second time.
@Citynumbers, no PHP 4 version is available at the moment (or in the near future).
April 21st, 2009 at 12:18 am
thanks for a quick reply.
Senario:
I come in the first time click on sign in with twitter, twitter does its things send it back to my page. I save the 2 tokens in the database against the user. in that session the user wont have to go through that process again. But when the same user comes to my site on a different day from a different computer they would have to do the twitter auhtorizing again right?
April 21st, 2009 at 11:12 am
Hi jaisen, I’m having a problem.
Im confused why it verifies the user’s data - but the next time I try an API call it fails.
Posting tweets also works fine. The tokens are definitely correct (otherwise verifyCredentials would fail)
April 21st, 2009 at 11:17 am
Cracked it. Realised EpiTwitter is requesting http://twitter.com/trends.json instead of http://search.twitter.com/trends.json
Is the Search API implemented in EpiTwitter?
April 21st, 2009 at 11:40 am
@Sam, the search API isn’t implemented. It would be trivial to do though. I’ll read up on it and add support. I don’t believe it requires authentication (right?).
April 21st, 2009 at 1:25 pm
When i try to update user status, i get this error:
“Failed to validate oauth signature or token”
@dan,
I tried your solution (httpPost).
That leads to the following error:
( [request] => /statuses/update.json [error] => Could not authenticate you. )
Any pointers?
April 21st, 2009 at 1:54 pm
My post original comment is probably not longer relevant as I believe those bugs were fixed in a library updated.
April 21st, 2009 at 2:09 pm
@Kiran, @Dan’s correct that the library was updated to fix the problem he was having. Are you using the latest code from github?
Do you have source you can point me to?
April 21st, 2009 at 2:19 pm
Hey jaisen.
None of the Search API needs authentication.
I’m not sure whether we still need to send our oauth_token though (for twitter tracking which apps are using the search api)
April 21st, 2009 at 2:32 pm
Senario:
I come in the first time click on sign in with twitter, twitter does its things send it back to my page. I save the 2 tokens in the database against the user. in that session the user wont have to go through that process again. But when the same user comes to my site on a different day from a different computer they would have to do the twitter auhtorizing again right?
April 21st, 2009 at 2:41 pm
have a look at http://www.twittercontd.com/index_test.php
April 21st, 2009 at 3:15 pm
@Rahul, once you save the token and token secret…the user will not need to re-authorize again.
I tested your link and was able to update a status. However, if I refreshed the page it did not seem to maintain a session for me to post another update.
April 21st, 2009 at 3:16 pm
@Sam, cool. I’ll add support for the search API w/o OAuth. I’m unfamliar with it but it should be straightforward.
April 21st, 2009 at 3:27 pm
It looks like it’s just a different api url. http://search.twitter.com rather than http://twitter.com
the same get_trendsCurrent() method translating to /trends/current.json can still be used it seems.
loving epitwitter!
just looking at the code is helping with my php too. i never knew about __call()
April 21st, 2009 at 3:33 pm
@jaisen,
Seems to work now.
I logged into my twitter account, and revoked permissions on my app, and tried the whole thing again. This time it worked.
Thanks for library. Awesome!
April 21st, 2009 at 3:57 pm
I fixed the session state but I still have that question. Once the user authorise the app the second time around why does it ask “Deny or Allow”
April 21st, 2009 at 4:29 pm
@Sam take it for a test drive and let me know how it works.
http://github.com/jmathai/twitter-async/commit/daab3980bdd29ce8bea03d3439cb6994bfad4c59
April 22nd, 2009 at 8:33 pm
sir im having this kind of problem…
Fatal error: Call to undefined function curl_init() in C:\wamp\www\1\twitterOAuth.php on line 126
anywork around to fix it?
pls email me @ deathgroove@gmail.com
April 22nd, 2009 at 8:56 pm
can u help me with this i error thing….
Warning: require_once(PHPUnit/Framework.php) [function.require-once]: failed to open stream: No such file or directory in C:\wamp\www\123\php\tests\EpiOAuthTest.php on line 4
Fatal error: require_once() [function.require]: Failed opening required ‘PHPUnit/Framework.php’ (include_path=’.;C:\php5\pear’) in C:\wamp\www\123\php\tests\EpiOAuthTest.php on line 4
April 24th, 2009 at 1:44 am
hey, im stuck with the unicode twits right now. classic bug that i cant resolve. english twits go fine. unicode hebrew ones return Failed to validate oauth signature or token
can anyone help? i saw there was a ruby fix but i cant seem to implement it on this library.
help :(
April 24th, 2009 at 4:42 pm
Anyone getting this error?
Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /homepages/29/d204945174/htdocs/quizhubb/epi/EpiCurl.php on line 4
Was working just fine last night =/
April 24th, 2009 at 5:02 pm
Silly me…server was running PHP 4. Runs fine on PHP 5!
doh!
April 24th, 2009 at 8:29 pm
@alon, can you paste in the string you were getting errors with? I’ll have a look at fixing it.
April 24th, 2009 at 8:32 pm
I merged Arik’s code, which lets you deal with enumerated lists more naturally, into the master branch. This applies to endpoints like /statuses/followers.
Documentation has been updated as well: http://wiki.github.com/jmathai/twitter-async.
Please give it a try and report any issues here or directly at github - http://github.com/jmathai/twitter-async/issues.
April 25th, 2009 at 12:21 pm
@jaisen try updating a status with unicode text like
בוקר טוב
it will fail on authentication. i understood there was a fix for ruby for that. couldnt implement it for php.
$twitterObj = new EpiTwitter($consumer_key, $consumer_secret, $usertoken, $usersecrettoken);
$userInfo = $twitterObj->get_accountVerify_credentials();
$followers = $twitterObj->post_statusesUpdate(array(’status’ => $status));
return $followers->response;
April 25th, 2009 at 12:24 pm
@jaisen
http://code.google.com/p/twitter-api/issues/detail?id=433
April 25th, 2009 at 1:58 pm
@sam @jaisen
I test drove the search method - worked fine while authenticated with twitter.
Is the code setup to allow search to work while not authenticated? I can’t get it to work atm but think it should be able to.
I have called:
$twitterObj = new EpiTwitter($consumer_key, $consumer_secret);
and am trying:
$statuses = $twitterObj->get_search($search_terms);
which only works when authenticated…
April 25th, 2009 at 4:36 pm
@pete, mind checking to see if you’re being rate limited? Have a look at $statuses->responseText. I ran into this on Friday. If not, what’s responseText contain?
April 25th, 2009 at 8:20 pm
@alon, thanks for the tip. Fixed the problem and added unit tests for unicode support. Pushed to github.
April 25th, 2009 at 11:28 pm
@jaisen was my bad - fixed it now. will think twice before posting late at night…
thanks for the great package btw
April 26th, 2009 at 12:40 am
Thanks , this worked for me to add the app to twitter with OAuth…
It’s twitter mobile
http://m.mwd.com
April 26th, 2009 at 2:32 am
@jaisen Thanks alot for this code.
I updated my code to the latest released an encounter this error ‘Warning: Invalid argument supplied for foreach() in /home/.liebchen/username/domain/oauth/EpiTwitter.php on line 91′
I updated because I was having the ‘Failed to validate oauth signature or token’ when trying to post a status update.
I could get account credentials fine but when I called $twitterObj->post_statusesUpdate($params); directly afterwards I got the failed to validate problem.
Thanks for your time.
April 26th, 2009 at 2:57 am
Please disregard my last post as it turns out I was failing to call
after I had set the token via get parameter.
All is fine now. Thanks again.
April 26th, 2009 at 2:58 am
@Tom:
What are you using in the foreach. I was having that problem before. I was using:
$tweets = $twitterObj->get_statusesFriends_timeline();
foreach($tweets as $tweet)
but had to change it to
foreach($tweets->response as $tweet)
to get it to work.
Meanwhile I’m having trouble with search methods. Is
$searchResults = $twitterObj->get_search(array(’q’ => $_GET["q"]));
the right way to do it?
April 26th, 2009 at 3:09 am
Ok, disregard that… All working :) Sorry, wish this had edit and delete buttons :P
April 26th, 2009 at 9:06 am
@daniel, no problem. fyi - the latest version let’s you do:
foreach($tweets as $tweet) echo $tweet->text;
No longer required to use ->response.
April 27th, 2009 at 11:33 am
After a bunch of tries This works just great.
Thanks for your work.
It seems that the only way I could get
to work was by reading
$userInfo->responseText
Does that make any sense?
April 27th, 2009 at 12:04 pm
@phil, that’s correct. It’s part of the asynchronous nature of how this library works.
You need to read responseText (or any of the other response values) to ensure that the call was successful.
The benefit of this is that you can make the call, go about doing some other work and come back to retrieve the response. Most libraries will make the call and wait until a response is received prior to moving on.
Glad it’s working out for you.
April 28th, 2009 at 10:13 am
Hi there. thanks you very much for tutorial and api itself.
well I faced to isue that makes me crazy. The application works fine but when the user logs out from my application and login again Twitter asks me wheter I allow app to access my account or not.
I have seen several sitest that just retrives user back if he is currently logged at twitter.
Thanks in advance,
Umed
April 28th, 2009 at 10:40 am
I just got the latest code for the example provided. I registered a new application and replaced the consumer key and consumer secret. However, the authorization link in the start.php file keeps coming up with a blank oauth token parameter. I guess getRequestToken is not returning a token. Any ideas?
April 28th, 2009 at 10:49 am
ok. Just made some research and got that sites that doing that way are not using standart methods.
Sorry for taking time, Umed
April 28th, 2009 at 11:00 am
@Umed, You have to save the access tokens and then when the user comes back you can use them to make calls to twitter.
The user only has to allow your application access ONE time. If you’re making them do that over and over, then you’re not properly saving the access token :)
April 28th, 2009 at 3:28 pm
@Rav, Make sure that the consumer key and secret are correct. If the oauth_token is blank then there’s something wrong with the OAuth authentication.
April 28th, 2009 at 3:38 pm
@jaisen i am having the same problem as @Umed… i am saving the two tokens in the database but how will i know which user is logging in to retrieve from the database.
Could you please have a look at http://www.twittercontd.com/index_oauth_beta.php
Thanks
April 28th, 2009 at 8:55 pm
@Rahul, unless you plan on using the “sign in with Twitter” feature then you’ll need to have a user database of your own.
I think you’re looking for the ability for the user to sign into your site with Twitter, which is different from storing OAuth tokens for them in your own database.
Anyone else care to weigh in on this? I don’t think I’m explaining it well :).
April 28th, 2009 at 10:44 pm
@jaisen sorry but I am still confused. I have the “sign in with Twitter” feature on my site (have a look at the link).
So first time user logs in using twitter I get back 2 tokens from twitter for that user. Now I can perform changes for that user for the given session. The next time the same user comes back then he wont have to have “Deny or Allow” again but in my case he has to.
The first time i will save the 2 tokens in my database (which I have). But the next time the same user comes back then what?
April 28th, 2009 at 11:01 pm
@Jaisen, @Umed - don’t you have to use another url endpoint in order to skip the “allow application” screen after the user already authorized you?
April 29th, 2009 at 7:20 am
@Rahul, the flow to “sign in with Twitter” is slightly different than the flow described here. @arik is correct in that you have to use a different endpoint (not covered in this blog post). Here is documentation for it: http://apiwiki.twitter.com/Sign-in-with-Twitter.
Basically, once a user has allowed your application you can access the /oauth/authenticate endpoint (not mentioned here). This endpoint will check if the user is logged in to Twitter and whether or not they’ve granted your application access. Once the checks are completed then the user will be redirected to your site with the access token and token secret.
Perhaps I should write a quick blog post on how to use EpiTwitter with the sign in with Twitter flow.
Does that help clarify?
April 29th, 2009 at 12:44 pm
@jaisen I’m having the same problem as @Vaibhav. I’m getting this in start.php after updating the key and secret.
http://twitter.com/oauth/authorize?oauth_token=
Thanks!
April 29th, 2009 at 1:23 pm
@Mike or @Viabhav do either of you have a place where I can log in and have a look? Does the yapache error log show any messages?
It’s hard for me to diagnose without taking a look at the problem myself.
April 29th, 2009 at 3:53 pm
@jaisen thank you for your help. But a quick blog post will be awesome. It will help me and also the others.
April 29th, 2009 at 11:44 pm
@Rahul etc if you want to use Twitter for login, and hence not store each user’s keys in your own db, then select that checkbox in your app’s settings.
I then added the following to EpiOAuth.php:
protected $authenticateUrl; public function getAuthenticationUrl() { $retval = "{$this->authenticateUrl}?"; $token = $this->getRequestToken(); return $this->authenticateUrl . '?oauth_token=' . $token->oauth_token; }and the following to EpiTwitter.php:
you can then use:
to point your users to the login workflow, rather than always sending them to the allow screen.
April 30th, 2009 at 1:40 pm
Please forgive me for asking this question. But I’ve figured out who to use the api to write direct messages and it works like a charm. What I can’t figure out or find is the api feature that lets me post public tweets for a user that has connected to my application. Can somebody point me to this in the documentation or tell me if it exist at all?
Thanks phil
April 30th, 2009 at 7:08 pm
@pete, feel free to fork the repository at github and make a pull request for me to merge in your changes into the master branch.
@phil, to post to a user’s status you need to use that user’s token and token secret when creating the EpiTwitter object (or use setToken if already created). Then all calls will be made on behalf of that user, including ones to update status.
April 30th, 2009 at 11:53 pm
Added “Sign in with Twitter” support and wrote a blog post about it. http://www.jaisenmathai.com/blog/2009/04/30/letting-your-users-sign-in-with-twitter-with-oauth/
Working example: http://www.jaisenmathai.com/sign_in_with_twitter/
May 1st, 2009 at 12:33 am
@jaisen, thanks again. I apologize. Works like a charm.
The hacker in me - jumped in and started doing things without reading the documentation. My Bad
Phil
May 1st, 2009 at 5:06 pm
Thanks a lot works like a charm
May 2nd, 2009 at 8:05 am
Sorry, I feel really dumb, but I can’t figure out how to allow status updates using your library. Everything worked perfect as far as logging in and saving tokens with cookies, etc.
May 2nd, 2009 at 9:41 am
I use
$post_tweet = "Heres the test"; // update the status $update_status = $twitterObj->post_statusesUpdate(array('status' => $post_tweet)); // get the ID of the tweet just sent $tweet_id = $update_status->response['id'];May 4th, 2009 at 1:00 pm
hi,
i am having an issue with the
get_friendshipsExist() return values. i dont seem to get a correct reponse.
$checkfollow =$twitterObj->get_friendshipsExists(array('user_a'=>$twitterInfo2->screen_name,'user_b'=>$st2[1])); if($checkfollow->following)pls help with a correct method for getting the boolean response
May 4th, 2009 at 5:37 pm
@Gopu, I fixed the issue you were having and committed to github. $res->response always contains the json decoded value. That’s what you’ll want to check if it’s true or false.
Thanks for reporting the bug.
May 11th, 2009 at 6:39 am
So after evaluating Twitter PHP Libraries for a project I’m working on, I really like EpiTwitter. The major problem I see going forward is OAuth. My project is a mobile website, and from first glance OAuth doesn’t seem feasible from a mobile browser. Is this one of the user cases for basic authentication they are waiting to solve before removing basic auth?
Any advice on a mobile browser approach to OAuth would be appreciated.
(I also think at this point EpiTwitter could benefit from a forum).
May 14th, 2009 at 2:04 am
Thanks for the tutorial, I were developing a Twitter application for Joomla and it’s really helpful.
May 15th, 2009 at 1:11 am
Hey guys,
is anybody else having this problem? I have two apps registered at Twitter. Both are working fine with OAuth. I can access (read/write) data from Twitter.
While the first app shows “from source” correctly, the second app doesnt.
Instead of “from source” it shows “from web”.
Maybe a Twitter bug? What do you think?
Best wishes,
Michael
May 15th, 2009 at 3:58 am
Hello All,
I have set up the library code but in start.php it redirects to “http://twitter.com/oauth/authorize?oauth_token=”
Over here the oauth_token is missing.
Can anyone please help how to solve it?
May 15th, 2009 at 5:04 am
Hello,
is it possible to avoid registration step?
Can anyone answer if the following is possible:
1. On a site user may tweet which article they are reading by checking an option(a checkboc).
2. will just fill in the tweeter username ( and password if neccessary, i don’t know if it is mandatory)
3. then onward, the site will tweet what topic the user is reading now with the application name like
“reading …..” 1hour ago from MY_SITE_APP
4. The user should not be taken to twitter site to approve the application.
is it possible or the must have to taken to the registration page ?
May 15th, 2009 at 5:36 am
@Shaikh Sonny Aman:
What you are planning isnt possible.
With OAuth the user is always redirected to twitter.com for approval.
>> “reading …..” 1hour ago from MY_SITE_APP
Only possible with OAuth authentication.
If you dont want to use OAuth, you can authenticate the user with his screen name and password. In this case, the user is not redirected to twitter.com.
Cheers,
Michael
May 15th, 2009 at 6:01 am
Thank you very much for your reply and so quickly!
All the best!
Aman
May 15th, 2009 at 8:07 am
@michael, that seems like it would be an issue on Twitter’s end. I know it’s come up on the Twitter Development Talk group before.
@hiren, did you update secret.php with your consumer key and secret?
May 15th, 2009 at 8:12 am
@jaisen, Yes I have updated the secret.php
May 15th, 2009 at 8:23 am
@hiren, make sure you’re running php 5.2 or higher. If you still have problems then feel free to send me the files you’re working with and I’ll have a look.
May 15th, 2009 at 8:35 am
@jaisen, oh.. its 5.1.4.. do I have to upgrade it to 5.2 or higher?
May 15th, 2009 at 8:37 am
@hiren, you’ll definitely need the json_* functions. They’re available for 5.1.4 as a pecl extension, or you can use the PEAR JSON_Services library and create your own json_* functions which wrap theirs.
If you can upgrade to 5.2 without any problems, it might be worthwhile anyways :).
May 16th, 2009 at 2:49 pm
Hi, I need to do an operation which is pretty hard on twitter’s servers. In the past when I tested this with basic auth I would hit twitter’s limit and be blocked for an hour. So what I plan is to throttle the requests myself by building a queue and then a cron job that will issue the requests slowly enough for me not to piss off twitter. I guess I would have to have the tokens saved with the queued item. (Right now I am just cookie-ing them to the user but the user and his browser won’t be there when this cron job kicks in. ) I hoped to avoid a database for this little twick. Has anyone done anything like this and is there any security concern?
May 16th, 2009 at 6:01 pm
@Colleen, storing the tokens in your database is less of a security risk than storing passwords. In order to make use of the tokens you need the consumer key and secret. However, keep them safe!
You can request to be whitelisted so you don’t keep hitting the limits and getting blocked. http://apiwiki.twitter.com/FAQ#IkeephittingtheratelimitHowdoIgetmorerequestsperhour
May 17th, 2009 at 7:42 am
Yes indeed. I have the consumer key and secret those are constant as far as I’m concerned so they are configuration items. Oh looks like a liteweight SQL database.
Thanks for the link on whitelisting. I thought you had to pass some kind of test to get whitelisted.
May 18th, 2009 at 3:53 am
@jaisen, thanks for the reply and its really helpful. Now the further problem is, how to use the Post Method?
I just want to have the two textboxes on my form (ie. username and password) and then I want to submit it. Is that possible?
Thanks
May 20th, 2009 at 12:10 am
@Hiren, if the username/password fields you’re talking about are for their Twitter credentials - then you won’t need those. The point of OAuth is so you don’t have to collect them from your users.
For more information see this blog post: http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html
May 24th, 2009 at 6:40 am
I’m trying to read a users timeline without being locked in, and I always get an error of “Invalid expired token”. Seems like I have to be authorized to read a users timeline (which is not protected), but the API documentations says:
Requires Authentication (about authentication):
true, if requesting a protected user’s timeline
Am I doing something wrong?
May 24th, 2009 at 7:20 am
i got an issue.
$consumer_key = TwitterConsumer::key(); $consumer_secret = TwitterConsumer::secret(); $twitterObj = new EpiTwitter($consumer_key, $consumer_secret, USER_TOKEN, USER_SECRET_TOKEN); $userInfo = $twitterObj->get_accountVerify_credentials(); $timeline = $twitterObj->post_favoritesCreate(array('id' => $id));when i try the above. it responds in
{”request”:”\/favorites\/create.json”,”error”:”This method requires a GET.”}
when i change the post_ to get_ i get
{”request”:”\/favorites\/create.json?id=1472669360″,”error”:”Invalid \/ used nonce”}
what todo?
May 24th, 2009 at 7:38 am
btw, their api states the favorites/create requires POST. so its a tad bizarre.
May 24th, 2009 at 8:29 am
Alon - have you tried the following:
$method = "post_favoritesCreate{$id}"; $timeline = $twitterObj->$method();?
May 24th, 2009 at 8:32 am
Actually maybe you need to add a ‘_’ somewhere there, but my point was that id isn’t a parameter for this API call, but part of the url…
May 24th, 2009 at 8:36 am
@alon: have you tried something like this:
$twitterObj->{'post_favoritesCreate'.$id}(array('id' => $id));May 24th, 2009 at 9:43 am
Arik. you rock!
$method = “post_favoritesCreate{$id}”;
$timeline = $twitterObj->$method();
Works!
May 26th, 2009 at 6:56 pm
I’ve can do other things with library but
This tells me
Failed to validate oauth signature or token
What could I be missing?
Tks,
Phil
May 30th, 2009 at 12:04 pm
Hey dude. I’m having probelms calling the following:
$get_friends = $twitterObj->get_friendsIds(array('id' => $_SESSION['my_twitter_id']));$get_friends->responseText gives me the Twitter Error page (”Something is technically wrong.”)
Wondering if you can call the get_FriendsIds without any problems?
Thanks
June 9th, 2009 at 4:35 pm
Several of you had asked about uploading profile/background images. I’ve added image support and committed it to a separate branch on GitHub.
It’s currently at: http://github.com/jmathai/twitter-async/tree/multipart and docs are available as well: http://wiki.github.com/jmathai/twitter-async#multipart.
I have two unit tests for it but would like more usage before I merge it into master. Let me know if you get a chance to try it out.
June 10th, 2009 at 11:53 am
im checking it now jaisen, thanks for the quick update ! :) you rock.
June 10th, 2009 at 11:05 pm
hey.. twitter has put back callback url support in oauth. Can we use it with your api.
June 11th, 2009 at 1:18 am
thanks! the background image uploading worked perfectly at my server. Thanks.
June 11th, 2009 at 1:23 am
How do I specify tiled or not in this function?
$twitterObj->post_accountUpdate_profile_image(array('@image' => '@/tmp/myfile.jpg'));June 11th, 2009 at 2:24 am
just an update. jaisen it works great. uploaded picture works fine. Only issue is that twitter has problems with updating the api with the correct image url. so after user uploads the picture the correct url updates only in the username.xml and not in .json.
prevents us from deploying it to production.
June 11th, 2009 at 7:53 am
@aloncarmel2k, thanks for the update. i’ve also noticed that uploading pngs returns a 200 response but does not update the image.
@nishant, you should be able to do the following:
$twitterObj->post_accountUpdate_profile_image(array('@image' => '@/tmp/myfile.jpg'), 'tile' => 'true');June 11th, 2009 at 1:00 pm
I’m running into an issue here. Here’s my code:
$twitterInfo2= $twitterObj->get_accountVerify_credentials(); $twit_id = $twitterInfo2->screen_name; echo "you are:$twit_id!"; $exists = $twitterObj->get_friendshipsExists(array('user_a' => $twit_id, 'user_b' => 'patrickcurl')); echo $exists->responseText;The way twtfollow works is when you join it you follow 10 people - your sponsors, then you recruit people and they recruit people, etc… to get more followers on twitter.
What I’m trying to do is
IF follower already exists skip, else follow.
Right now I’m just testing the If exists part of this and I’m getting an error:
Warning: Invalid argument supplied for foreach() in /home/patrickc/public_html/twtfollow.com/test/oauth/EpiTwitter.php on line 105
true
As you see it did work - but it threw an error too - do you know why this error is being thrown?
June 11th, 2009 at 1:23 pm
Actually I think I fixed it -I got the latest versions of the twitter asynch files and now seems fixed.
June 11th, 2009 at 2:11 pm
Now running into another issue…. How do I get the friendshipCreate post method to work?
I’m trying this:
$twitterObj->post_friendshipsCreate(array('screen_name' => 'problogger'));but it’s not working, any ideas?
June 11th, 2009 at 4:14 pm
@Patrick, Try passing in id instead of screen_name. The docs say screen_name is required but I believe that to be an error. It’s generally used for disambiguation. I added a couple unit tests to verify that the friendships* endpoints work.
For reference: http://github.com/jmathai/twitter-async/commit/95ec403873fc8e789ecdbcfda5a55f05a6a55714
June 11th, 2009 at 9:07 pm
Hi,
I tested my application yesterday without any error. But today I am getting Invalid token error everytime. Do you have any idea what can be the issue.
June 11th, 2009 at 9:40 pm
I solved the invalid token error. I am not sure how it got solved. :)
June 12th, 2009 at 12:10 am
ok, running into another problem - anyone know how I can check to see if someone’s account is protected - ie can’t be autofollowed by my script?
I’m using
if ($twit_id === $s_spid5) { echo "skipping, this is you!"; } else { $exists = $twitterObj->get_friendshipsExists(array('user_a' => $twit_id, 'user_b' => $s_spid5)); if($exists->response) { echo "Already following @$s_spid5"; } else { $create = $twitterObj->post_friendshipsCreate(array('id' => $s_spid5)); $create->responseText; echo "Successfully followed @$s_spid5"; } }this checks if the twit_id and user are the same (mostly in testing)
Checks if friendship already exists if it does skip it.
Create Friendship if doesn’t exist.
Error:
Fatal error: Uncaught exception ‘EpiOAuthException’ with message ‘{”request”:”\/friendships\/exists.json?user_a=patrickcurl&user_b=joyce_j”,”error”:”You do not have permission to retrieve following status for both specified users.”}’ in /home/patrickc/public_html/twtfollow.com/test/oauth/EpiOAuth.php:301 Stack trace: #0 /home/patrickc/public_html/twtfollow.com/test/oauth/EpiTwitter.php(123): EpiOAuthException::raise(’{”request”:”\/f…’, 403) #1 /home/patrickc/public_html/twtfollow.com/test/confirm.php(101): EpiTwitterJson->__get(’response’) #2 {main} thrown in /home/patrickc/public_html/twtfollow.com/test/oauth/EpiOAuth.php on line 301
June 12th, 2009 at 12:34 am
@Patrick, I don’t believe there’s an api for that. You could catch the EpiOAuthException exception and ignore it.
try { $exists = $twitterObj->get_friendshipsExists(array('user_a' => $twit_id, 'user_b' => $s_spid5)); if($exists->response) { echo "Already following @$s_spid5"; } else { $create = $twitterObj->post_friendshipsCreate(array('id' => $s_spid5)); $create->responseText; echo "Successfully followed @$s_spid5"; } } catch(EpiOAuthException $e) { echo "Don't have permission to do this"; }June 12th, 2009 at 1:11 am
ok, thanks - maybe I should suggest it to Twitter that they add it.
June 13th, 2009 at 1:14 am
It may be just really late and my mind is fried from staring at the pc - but I’m wanting to make automated tasks like for instance sending an update every day for a certain user using cron jobs.
Is that possible with oauth?
Also isn’t oauth_token and oauth_token_secret supposed to be unique values relatiive to the twitter id- are these what I would pass to the cronjob to authenticate the user when doing automated tasks?
I’ve registered 3 diff twitter ids on my app, and they all have the same token and secret token.
I think I’m a little confused - but this is my first php app ever, so I’m entitled to some confusion…
Any advice would be wonderful.
June 13th, 2009 at 4:03 am
Sorry to ask a million questions - but sometimes I’m noticing that I get this error during testing:
Fatal error: Cannot redeclare class EpiCurl in /home/patrickc/public_html/twtfollow.com/oauth/EpiCurl.php on line 3
If I go back, refresh the screen then try again it works fine…. any ideas?
it’s on my logout page - I clear all the cookies, then I have the authenticate url for them to click to sign back in if they want to…
June 13th, 2009 at 6:32 am
Patrick,
Yes,
I call a function that looks like this
function UpdateTwitterStatus($consumer_key, $consumer_secret, $ut, $uts,$statusmessagearr)
{
$twitterObjforSend = new EpiTwitter($consumer_key, $consumer_secret, $ut, $uts);
$userInfo = $twitterObjforSend->post_statusesUpdate($statusmessagearr);
$statusresponse = $userInfo->response;
return $statusresponse;
}
Where $ut and $uts is the users token and users secret token respectively of the user that the status message is for.
Phil
June 13th, 2009 at 6:24 pm
hey phil thanks!
June 13th, 2009 at 8:50 pm
Anyone else getting an error like this?: Fatal error: Cannot redeclare class EpiCurl in /home/patrickc/public_html/twtfollow.com/oauth/EpiCurl.php on line 3
June 14th, 2009 at 7:33 am
@Patrick, somehow you’re including the file more than once. It could be a circular reference or something which could be solved by an include_once. If include_once doesn’t work then try and track down how it might be included multiple times.
June 14th, 2009 at 7:55 am
@jaisen you should really stop helping people in comments and direct to somewhere more productive. :)
June 16th, 2009 at 6:54 am
[...] are over at http://toys.lerdorf.com/archives/50-Using-pecloauth-to-post-to-Twitter.html and http://www.jaisenmathai.com/blog/2009/03/31/how-to-quickly-integrate-with-twitters-oauth-api-using-p... Still — [...]
August 11th, 2009 at 9:58 pm
[...] to sign into your site with their twitter username and password. I recently wrote a blog post on how to use Twitter’s OAuth API. This feature is a natural progression in allowing Twitter users to securely sign into your [...]
September 2nd, 2009 at 8:59 pm
[...] 9. How to quickly integrate with Twitter’s OAuth API using PHP [...]
November 18th, 2009 at 3:47 am
[...] | jaisenmathai.com (en [...]
December 21st, 2009 at 2:17 am
[...] oAuth Hallo, mithilfe dieses Tutorials (How to quickly integrate with Twitter’s OAuth API using PHP :: Jaisen Mathai) versuche ich es zu realisieren, dass meine Benutzer sich sofort oder später mit Twitter verbinden [...]