git.gnu.io has moved to IP address 209.51.188.249 -- please double check where you are logging in.

Commit 500f0c70 authored by Zach Copley's avatar Zach Copley Committed by Evan Prodromou

Make the TwitterQueuehandler post to Twitter using OAuth

parent e9edaab3
......@@ -67,39 +67,57 @@ class TwitterauthorizationAction extends Action
if (empty($this->oauth_token)) {
// Get a new request token and authorize it
try {
$client = new TwitterOAuthClient();
$req_tok = $client->getRequestToken();
// Get a new request token and authorize it
// Sock the request token away in the session temporarily
$client = new TwitterOAuthClient();
$req_tok = $client->getRequestToken();
$_SESSION['twitter_request_token'] = $req_tok->key;
$_SESSION['twitter_request_token_secret'] = $req_tok->key;
// Sock the request token away in the session temporarily
$_SESSION['twitter_request_token'] = $req_tok->key;
$_SESSION['twitter_request_token_secret'] = $req_tok->key;
$auth_link = $client->getAuthorizeLink($req_tok);
} catch (TwitterOAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));
}
$auth_link = $client->getAuthorizeLink($req_tok);
common_redirect($auth_link);
} else {
// Check to make sure Twitter sent us the same request token we sent
// Check to make sure Twitter returned the same request
// token we sent them
if ($_SESSION['twitter_request_token'] != $this->oauth_token) {
$this->serverError(_('Couldn\'t link your Twitter account.'));
}
$client = new TwitterOAuthClient($_SESSION['twitter_request_token'],
$_SESSION['twitter_request_token_secret']);
try {
// Exchange the request token for an access token
$client = new TwitterOAuthClient($_SESSION['twitter_request_token'],
$_SESSION['twitter_request_token_secret']);
$atok = $client->getAccessToken();
// Exchange the request token for an access token
// Save the access token and Twitter user info
$atok = $client->getAccessToken();
$client = new TwitterOAuthClient($atok->key, $atok->secret);
// Save the access token and Twitter user info
$twitter_user = $client->verify_credentials();
$client = new TwitterOAuthClient($atok->key, $atok->secret);
$twitter_user = $client->verify_credentials();
} catch (OAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));
}
$user = common_current_user();
......
......@@ -645,13 +645,14 @@ function mail_twitter_bridge_removed($user)
$subject = sprintf(_('Your Twitter bridge has been disabled.'));
$body = sprintf(_("Hi, %1\$s. We're sorry to inform you that your " .
'link to Twitter has been disabled. Your Twitter credentials ' .
'have either changed (did you recently change your Twitter ' .
'password?) or you have otherwise revoked our access to your ' .
"Twitter account.\n\n" .
'You can re-enable your Twitter bridge by visiting your ' .
"Twitter settings page:\n\n\t%2\$s\n\n" .
$site_name = common_config('site', 'name');
$body = sprintf(_('Hi, %1$s. We\'re sorry to inform you that your ' .
'link to Twitter has been disabled. We no longer seem to have ' .
'permission to update your Twitter status. (Did you revoke ' .
'%3$s\'s access?)' . "\n\n" .
'You can re-enable your Twitter bridge by visiting your ' .
"Twitter settings page:\n\n\t%2\$s\n\n" .
"Regards,\n%3\$s\n"),
$profile->getBestName(),
common_local_url('twittersettings'),
......@@ -679,11 +680,11 @@ function mail_facebook_app_removed($user)
$site_name = common_config('site', 'name');
$subject = sprintf(
_('Your %1\$s Facebook application access has been disabled.',
_('Your %1$s Facebook application access has been disabled.',
$site_name));
$body = sprintf(_("Hi, %1\$s. We're sorry to inform you that we are " .
'unable to update your Facebook status from %2\$s, and have disabled ' .
'unable to update your Facebook status from %2$s, and have disabled ' .
'the Facebook application for your account. This may be because ' .
'you have removed the Facebook application\'s authorization, or ' .
'have deleted your Facebook account. You can re-enable the ' .
......
......@@ -360,104 +360,72 @@ function is_twitter_bound($notice, $flink) {
function broadcast_twitter($notice)
{
$flink = Foreign_link::getByUserID($notice->profile_id,
TWITTER_SERVICE);
if (is_twitter_bound($notice, $flink)) {
$fuser = $flink->getForeignUser();
$twitter_user = $fuser->nickname;
$twitter_password = $flink->credentials;
$uri = 'http://www.twitter.com/statuses/update.json';
$user = $flink->getUser();
// XXX: Hack to get around PHP cURL's use of @ being a a meta character
$statustxt = preg_replace('/^@/', ' @', $notice->content);
$options = array(
CURLOPT_USERPWD => "$twitter_user:$twitter_password",
CURLOPT_POST => true,
CURLOPT_POSTFIELDS =>
array(
'status' => $statustxt,
'source' => common_config('integration', 'source')
),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FAILONERROR => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => "Laconica",
CURLOPT_CONNECTTIMEOUT => 120, // XXX: How long should this be?
CURLOPT_TIMEOUT => 120,
# Twitter is strict about accepting invalid "Expect" headers
CURLOPT_HTTPHEADER => array('Expect:')
);
$ch = curl_init($uri);
curl_setopt_array($ch, $options);
$data = curl_exec($ch);
$errmsg = curl_error($ch);
$errno = curl_errno($ch);
$client = new TwitterOAuthClient($flink->token, $flink->credentials);
if (!empty($errmsg)) {
common_debug("cURL error ($errno): $errmsg - " .
"trying to send notice for $twitter_user.",
__FILE__);
$status = null;
$user = $flink->getUser();
try {
$status = $client->statuses_update($statustxt);
} catch (OAuthClientCurlException $e) {
if ($errmsg == 'The requested URL returned error: 401') {
common_debug(sprintf('User %s (user id: %s) ' .
'has bad Twitter credentials!',
$user->nickname, $user->id));
if ($e->getMessage() == 'The requested URL returned error: 401') {
// Bad credentials we need to delete the foreign_link
// to Twitter and inform the user.
$errmsg = sprintf('User %1$s (user id: %2$s) has an invalid ' .
'Twitter OAuth access token.',
$user->nickname, $user->id);
common_log(LOG_WARNING, $errmsg);
remove_twitter_link($flink);
// Bad auth token! We need to delete the foreign_link
// to Twitter and inform the user.
return true;
remove_twitter_link($flink);
return true;
} else {
} else {
// Some other error happened, so we should try to
// send again later
// Some other error happened, so we should probably
// try to send again later.
return false;
}
$errmsg = sprintf('cURL error trying to send notice to Twitter ' .
'for user %1$s (user id: %2$s) - ' .
'code: %3$s message: $4$s.',
$user->nickname, $user->id,
$e->getCode(), $e->getMessage());
common_log(LOG_WARNING, $errmsg);
return false;
}
}
curl_close($ch);
if (empty($data)) {
common_debug("No data returned by Twitter's " .
"API trying to send update for $twitter_user",
__FILE__);
if (empty($status)) {
// XXX: Not sure this represents a failure to send, but it
// probably does
// This could represent a failure posting,
// or the Twitter API might just be behaving flakey.
return false;
$errmsg = sprint('No data returned by Twitter API when ' .
'trying to send update for %1$s (user id %2$s).',
$user->nickname, $user->id);
common_log(LOG_WARNING, $errmsg);
} else {
// Twitter should return a status
$status = json_decode($data);
return false;
}
if (empty($status)) {
common_debug("Unexpected data returned by Twitter " .
" API trying to send update for $twitter_user",
__FILE__);
// Notice crossed the great divide
// XXX: Again, this could represent a failure posting
// or the Twitter API might just be behaving flakey.
// We're treating it as a failure to post.
$msg = sprintf('Twitter bridge posted notice %s to Twitter.',
$notice->id);
common_log(LOG_INFO, $msg);
return false;
}
}
}
return true;
......@@ -480,17 +448,20 @@ function remove_twitter_link($flink)
// Notify the user that her Twitter bridge is down
if (isset($user->email)) {
$result = mail_twitter_bridge_removed($user);
if (!$result) {
$msg = 'Unable to send email to notify ' .
"$user->nickname (user id: $user->id) " .
'that their Twitter bridge link was ' .
"$user->nickname (user id: $user->id) " .
'that their Twitter bridge link was ' .
'removed!';
common_log(LOG_WARNING, $msg);
}
}
}
......@@ -2,6 +2,8 @@
require_once('OAuth.php');
class OAuthClientCurlException extends Exception { }
class TwitterOAuthClient
{
public static $requestTokenURL = 'https://twitter.com/oauth/request_token';
......@@ -54,6 +56,16 @@ class TwitterOAuthClient
return $twitter_user;
}
function statuses_update($status, $in_reply_to_status_id = null)
{
$url = 'https://twitter.com/statuses/update.json';
$params = array('status' => $status,
'in_reply_to_status_id' => $in_reply_to_status_id);
$response = $this->oAuthPost($url, $params);
$status = json_decode($response);
return $status;
}
function oAuthGet($url)
{
$request = OAuthRequest::from_consumer_and_token($this->consumer,
......@@ -91,19 +103,26 @@ class TwitterOAuthClient
// Twitter is strict about accepting invalid "Expect" headers
CURLOPT_HTTPHEADER => array('Expect:')
);
);
if (isset($params)) {
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $params;
}
if (isset($params)) {
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $params;
}
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if ($response === false) {
$msg = curl_error($ch);
$code = curl_errno($ch);
throw new OAuthClientCurlException($msg, $code);
}
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
curl_close($ch);
curl_close($ch);
return $response;
return $response;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment