Dealing with Twitter's Ups and Downs - API - php

I make use of a great class made by Jaisen: http://github.com/jmathai/twitter-async/tree/master. Recently twitter has been up and down and I am sure it will continue to be the same in the future so I am trying to cut down on my dependency on twitter being actually working.
The following is what I have in my header.php and it is right at the top and it generates the login URL for each user. If twitter is down, my site hangs for as long as it needs to and it throws an exception. So I have to catch these expceptions which I have sort of done.
I now want to just cancel the request to the API after a few seconds and just load the page and keep trying behind the scenes. How can I best do this?
<?php include './twitter/EpiCurl.php'; include './twitter/EpiOAuth.php'; include './twitter/EpiTwitter.php';
$consumer_key = 'mykey';
$consumer_secret = 'mysecret';
$twitterObj = new EpiTwitter($consumer_key, $consumer_secret);
try{
$twiturl = $twitterObj->getAuthenticateUrl();
$url = "window.open('".$twiturl."','Login', 'left=20,top=20,width=500,height=500,toolbar=0,resizable=1'); startLoad();";
}catch(EpiOAuthBadRequestException $e){
// bad request exception do something
$statusMessage = 'Oops an error has occurred: ' . $e->getMessage();
}catch(EpiOAuthUnauthorizedException $e){
// bad authorization..probably bad tokens, do something different
$statusMessage = 'Oops an error has occurred: ' . $e->getMessage();
}catch(EpiOAuthException $e){
// uh oh, unknown oauth exception
$statusMessage = 'Oops, an unknown authorisation error has occurred! The mojo team have been notified! Please try again.';
}
if(isset($statusMessage)){
}
?>
Any improvement of the above code will also be appreciated.
Thanks all

The library supports a value to be passed into the curl timeout.
$twitterObj->setTimeout($secs_request_timeout);
I just added support for passing in a connection timeout as well. Unable to run unit tests because I'm being rate limited. Will commit this once I can verify that it works.
$twitterObj->setTimeout($secs_request_timeout, $secs_connection_timeout);

Use curl_setopt(CURLOPT_CONNECTTIMEOUT, 1 /* 1 second timeout */); to cause CURL to give up if a connection isn't established in 1 second. I use this when connecting to the facebook API, 'cause they've been pretty unreliable in the past as well.

Related

PHP Twilio - help needed to catch authentication errors

I am new to the Twilio PHP API and am finding it difficult using the sample code and even finding the correct documentation on the Twilio site to help me implement SMS messaging into our web app.
After much trial and error, and reading through some postings on this site, I have gotten far enough to figure out how to send a simple SMS message and even use a try/catch structure to deal with bad recipient phone numbers.
What I cannot for the life of me figure out is how to catch authentication errors with a client's SID and AUTH token. I'd like to catch authentication errors for a client's credentials before I try even sending messages for them. Some clients may blast a message to 200 customers so I don't want to spin my wheels if their authenticaiton fails. Heres what I have been trying:
require_once K_DOCROOT.'/includes/twilio-php-main/src/Twilio/autoload.php';
// use Twilio\Rest\Client;
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = "ACf6eXXXGGGDDDDDDDDDDDDDDDDDDDDDDD"; // intentionally incorrect
$token = "164d3a88f753e553691960fb4d405f82";
$dest = "+15106443333"; // recipient number
try {
$twilio = new Twilio\Rest\Client($sid, $token); // Had to change this to make it work without the USE above
// $message = $twilio->messages->create($dest, // to
// [
// "body" => "Testing 123",
// "from" => "+19998887777"
// ]
// );
//
// echo "Results: ".$message->sid;
}
catch (Exception $e) {
echo $e->getCode()." : ".$e->getMessage();
}
When I run this without the $twilio->messages->create() code, I get nothing... no errors, no responses whatsoever. If I uncomment the create() section where I try and send a message, I get the following:
20003 : [HTTP 401] Unable to create record: Authentication Error - invalid username
Which makes sense. But it is forcing me to catch the authentication error when sending a message and not before.
Maybe I am missing something, but is there some way to check for authentication errors, or get back some sort of status code letting me know a client's authentication was successful or not?
Also, if you have a link to the documentation that covers error handling for Client() calls, I would greatly appreciate it.

Checking signature in WS* server implementation

I want to verify a signature for a soap request on a soap server implemented in php.
The server code:
$Server = new SoapServer();
$d = new DOMDocument();
$d->load('php://input');
$s = new WSSESoapServer($d);
try {
if($s->process()) {
// Valid signature
$Server->handle($s->saveXML());
} else {
throw new Exception('Invalid signature');
}
} catch (Exception $e) {
echo "server exception: " . $e;
}
The error:
exception 'Exception' with message 'Error loading key to handle Signature' in /<path>/wse/src/WSSESoapServer.php:146
I have implemented a Client to sign SOAP requests using this library: https://github.com/robrichards/wse-php. There are no examples of how to implement the server...
How do I load the public key to check the signature?
[Edit]
I have now been able to load the supplied key using
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
$key->loadKey(CERT, true);
I am no longer getting an error message when validating the signature:
$x = new XMLSecurityDSig();
$d = $x->locateSignature($soapDoc);
$valid = $x->verify($key);
However, $valid is always false. I have no idea if it's because the key is loaded wrong or is actually invalid. I can find very little information on implementing a SOAP server with PHP and no information on implementing a SOAP server that relies on checking a signed request.
CLARIFICATION
My client talks to a remote web service and gets an acknowledgement.
Then the remote server takes some time to process my request.
A remote client (that I have no control over) then makes a request to
my service.
The last step is where I have trouble verifying the signature
Well anyways, your first approach looks fine to me, my server has the same structure. Unfortunately, WSSESoapServer does not inherit from SoapServer, thus is not really an SoapServer, but rather a SoapSignatureValidator and should be called like that. It would be easily possible to correct that behaviour, that one would not need a separate SoapServer instance (should be transparent and automatically).
<?php
require 'soap-server-wsse.php';
try {
// get soap message
$xmlSoap = DOMDocument::load('php://input');
// validate signature
$validateSignature = new WSSESoapServer($xmlSoap);
if(!$validateSignature->process())
file_put_contents("log.txt", "soapserver: SIGNATURE VALIDATION ERROR - CONTINUING WITHOUT SIGNATURE\n", FILE_APPEND);
//throw new Exception('Invalid Signature'); # this would cancel the execution and not send an answer
$sServer = new SoapServer($wsdl);
// actually process the soap message and create & send answer
//$sServer->setClass() or setObject() or set setFunction()
$sServer->handle($validateSignature->saveXML());
} catch (Exception $fault) {
file_put_contents("log.txt", "soapserver soapfault: ".print_r($fault, true), FILE_APPEND);
}
?>

Services_Twitter Pear PHP code - OAuth direct messages suddenly stopped working

I have the following PHP code, which up to a week or so ago was working to send Twitter direct messages to a particular user. I now get "HTTP_OAuth_Exception: Unable to connect to tcp://api.twitter.com:80. Error #0: php_network_getaddresses: getaddrinfo failed: Name of service not known in /usr/share/pear/HTTP/OAuth/Consumer.php on line 257"
I've searched around and can't find that anything has changed with Twitter since it was working and the server configuration also hasn't changed. I tried using SSL in case Twitter suddenly required connection via SSL, but that gave basically the same error (except it said ssl and port 443).
I'm at a loss to see what's wrong and don't believe anything changed on my side. My code is based on the example in the Services_Twitter documentation (http://pear.php.net/package/Services_Twitter/docs/latest/Services_Twitter/Services_Twitter.html#var$oauth)
Any help would be greatly appreciated.
require_once 'Services/Twitter.php';
require_once 'HTTP/OAuth/Consumer.php';
$twitterto = 'xxxxxxxxxxxx';
$message='This is a test message';
$cons_key='xxxxxxxxxxxx';
$cons_sec='xxxxxxxxxxxx';
$auth_tok='xxxxxxxxxxxx';
$tok_sec='xxxxxxxxxxxx';
try {
$twitter = new Services_Twitter();
$oauth = new HTTP_OAuth_Consumer($cons_key,
$cons_sec,
$auth_tok,
$tok_sec);
$twitter->setOAuth($oauth);
// The error is raised on the following line.
$twitter->direct_messages->new($twitterto, $message);
$twitter->account->end_session();
} catch (Services_Twitter_Exception $e) {
echo $e->getMessage();
}

LinkedIn API OAuth Problem

I'm using the PEAR OAuth Class to access the LinkedIn developer API and I've come across a bit of a problem. I can authorize my application but when it comes to getting an accessToken I'm receiving this error:
Edit:
Code after Adam's suggestions
public function oauth_access()
{
session_start();
$token = $_GET['oauth_token'];
$verifier = $_GET['oauth_verifier'];
$secret = $_SESSION['trequest_token_secret'];
$key = "****";
$secret = "****";
$oauthc = new OAuth($key, $secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_AUTHORIZATION);
$oauthc->setToken($token, $secret);
$oauthc->setNonce(rand());
try
{
$access_token_info = $oauthc->getAccessToken("https://api.linkedin.com/uas/oauth/accessToken");
$_SESSION['laccess_oauth_token']= $access_token_info['oauth_token'];
$_SESSION['laccess_oauth_token_secret']= $access_token_info['oauth_token_secret'];
$_SESSION['loauth_verifier'] = $verifier;
}
catch (OAuthException $e)
{
echo $e->getMessage();
}
}
But I'm now getting a different error:
Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)
You don't need to manually compute the signature, as pecl/oauth will do that for you.
Also, you're telling the library to pass the data in the Authorization HTTP header. That is a good place to have it. Then you are passing it via a query parameter. That is permitted, but less optimal. (You may actually be passing it in two places.) Also, pecl/oauth will automatically generate the proper timestamp.
When I first started, I found this blog post to be a good first start.
Or you can use the LinkedIn PHP library listed by Paul. It's also a good place to begin, if you don't want to reuse pecl/oauth because you're using that someplace else.

Zend GData Calendar: I can't use setUpdatedMin in the query [duplicate]

I have a problem with Updating and Deleting events using signed requests. Inserting events works just fine. But when Updating and Deleting I receive an "Unknown authorization header" 401 error.
For ALL three operations I first generate the client like this:
$client = new Zend_Gdata_HttpClient();
$client->setAuthSubPrivateKeyFile('certificates/gcalkey.pem', null, true);
$client->setAuthSubToken($session_token);
$gdataCal = new Zend_Gdata_Calendar($client);
To Update an event I use this:
$eventOld = $gdataCal->getCalendarEventEntry($eventUri);
$eventOld->title = $gdataCal->newTitle('NEW NAME');
try {
$eventOld->save();
} catch (Zend_Gdata_App_Exception $e) { print_r($e); exit; }
And it gives me the "Unknown authorization header" error. But the same code, using unsigned requests, works.
Where might be the problem? I tried modifying $eventUri to both https and http, but it seems it does not have any effect.
I've been getting this 401 error message too, creating the client and service the same way. It can retrieve a list of calendars, but fails when retrieving an event feed.
Has this worked for you before? It might not be officially supported yet.

Categories