views:

130

answers:

2

Hi everyone,

I've spent the last three hours trying to get a simple Twitter status update to work using Zend_Service_Twitter and Zend_Oauth_Token_Access. Infuriatingly, I keep getting the following response:

object(Zend_Rest_Client_Result)#34 (2) {
  ["_sxml:protected"]=>
  object(SimpleXMLElement)#39 (2) {
    ["request"]=>
    string(33) "/1/account/verify_credentials.xml"
    ["error"]=>
    string(20) "Invalid / used nonce"
  }
  ["_errstr:protected"]=>
  NULL
}

Here is the code I have tried:

$token = new Zend_Oauth_Token_Access();
$token->setToken('my token');
$token->setTokenSecret('my token secret');

$params = array('accessToken' => $token,
                'consumerKey' => 'my key',
                'consumerSecret' => 'my secret'
               );
$twitter = new Zend_Service_Twitter($params);

$response = $twitter->statusUpdate('simpletest');

What on Earth is a 'nonce'? If I mess up the token/token secret the error message in the response changes accordingly. However, with correct credentials I keep getting the above noncence (pun intended). Also, I have tried several alternatives such as the ones in this previous post on SO.

Any help would be appreciated!

Update:

In case it helps, or makes things easier, all I am trying to do is update the status of a single Twitter account, which is the application's twitter account. As I commented below @David Caunt's answer, whenever an 'item' gets posted to our site, the site's Twitter status will update to a brief description of the item as well as a link. That's all! This used to work, before oAuth became compulsory to make API calls (all that was needed was to instantiate a Zend_Service_Twitter and pass in our credentials).

+2  A: 

Consulting the reference manual, I believe your error is in creating the Zend_Service_Twitter object.

$twitter = new Zend_Service_Twitter(array(
    'username' => 'johndoe',
    'accessToken' => $token
));
$response   = $twitter->status->update('My Great Tweet');

You do not need to pass in the key and secret again, as they are contained in the access token used to sign the request.

See also my comment above explaining the nonce.

UPDATE:

I've tried the code in a minimal environment and you're right, it simply doesn't work.

You can see all of my code in a GitHub gist. It's deliberately minimal, avoiding MVC and other complications.

You may take comfort in the fact that a Zend_Http_Client returned from the Access Token does work.

David Caunt
Thanks for your comment and answer, David. I tried your suggestion but I'm still getting the exact same response. I'm really lost. There are four keys that Twitter provide: oauth_token, oauth_token_secret, Consumer Key and Consumer Secret. Don't I need all four of them?
karim79
You do need them all: the consumer key and secret are used to sign the request. The oauth token/secret are granted on a per user basis (when the user authorizes your application) and are therefore needed to make requests on behalf of a specific user. I'll run the code later and see if I can work out what you're doing wrong.
David Caunt
@David - I'm only trying to update the status of the app's twitter account, and not on behalf of users of the app. Basically, when an 'item' is added to our website that item's description and URL are used as the status update. Does this make any difference? Surely tweeting should be a lot simpler if it is only to *our* account, but I'm having trouble wrapping my head around this :) Thank you for all your help.
karim79
@David - I've started a bounty :)
karim79
Ah yes...I forgot about this one...will take a look
David Caunt
@karim79 I've updated my answer, take a look at the Gist
David Caunt
@David - Thank you! I actually got our twitter updates working again using Abraham's Twitter library at http://github.com/abraham/twitteroauth but I will scrap it and use the `Zend_Http_Client` snippet that you made.
karim79
Great, better to reduce the number of external libraries you are dependent on. I reported the issue to the component maintainer so hopefully it'll be fixed.
David Caunt
Oops, forgot to award you your 300 high-fives. There you go :)
karim79
Thanks - my first bounty, though I've seen more of them for PHP/ZF questions recently
David Caunt
+1  A: 

Twitter servers were reporting a problem with my nonces, when the error was in the signature.

My OAuth code was working for most requests, but when trying to post new statuses I was getting "Invalid / used nonce" as a response.

After much debugging, I found out I was failing to encode spaces as %20 and instead was sending them as +. After using the correct encoding, it worked flawlessly.

Twitter servers should have reported a problem with the signature, not the nonce.

I don't really expect you guys to waste any time fixing this (but it would be nice)... I just want to leave this note here so next time someone comes googling for "invalid / used nonce" they know they have to look at their encodings too.

From http://code.google.com/p/twitter-api/issues/detail?id=1059 (other solution in comments)

Chouchenos
@Chouchenos - Thank you for your answer. I actually read that thread the day I posted the question. I tried the encoding suggestion, as well as the double-encoding one, and got the same results. To eliminate this as a possibility, the tweet I'm using for testing is one word with no spaces. That said, I'm voting this up as it is relevant to the discussion and may help others.
karim79
Did you check that too : http://stackoverflow.com/questions/3022001/twitter-oauth-problem-with-frindship-create-in-api ?
Chouchenos