Make the TwitterQueuehandler post to Twitter using OAuth
This commit is contained in:
parent
e9edaab358
commit
500f0c7072
@ -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();
|
||||
|
||||
|
19
lib/mail.php
19
lib/mail.php
@ -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 ' .
|
||||
|
129
lib/twitter.php
129
lib/twitter.php
@ -360,106 +360,74 @@ 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,
|
||||
$client = new TwitterOAuthClient($flink->token, $flink->credentials);
|
||||
|
||||
# Twitter is strict about accepting invalid "Expect" headers
|
||||
CURLOPT_HTTPHEADER => array('Expect:')
|
||||
);
|
||||
$status = null;
|
||||
|
||||
$ch = curl_init($uri);
|
||||
curl_setopt_array($ch, $options);
|
||||
$data = curl_exec($ch);
|
||||
$errmsg = curl_error($ch);
|
||||
$errno = curl_errno($ch);
|
||||
try {
|
||||
$status = $client->statuses_update($statustxt);
|
||||
} catch (OAuthClientCurlException $e) {
|
||||
|
||||
if (!empty($errmsg)) {
|
||||
common_debug("cURL error ($errno): $errmsg - " .
|
||||
"trying to send notice for $twitter_user.",
|
||||
__FILE__);
|
||||
if ($e->getMessage() == 'The requested URL returned error: 401') {
|
||||
|
||||
$user = $flink->getUser();
|
||||
$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);
|
||||
|
||||
if ($errmsg == 'The requested URL returned error: 401') {
|
||||
common_debug(sprintf('User %s (user id: %s) ' .
|
||||
'has bad Twitter credentials!',
|
||||
$user->nickname, $user->id));
|
||||
// Bad auth token! We need to delete the foreign_link
|
||||
// to Twitter and inform the user.
|
||||
|
||||
// Bad credentials we need to delete the foreign_link
|
||||
// to Twitter and inform the user.
|
||||
|
||||
remove_twitter_link($flink);
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
// Some other error happened, so we should try to
|
||||
// send again later
|
||||
|
||||
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__);
|
||||
|
||||
// XXX: Not sure this represents a failure to send, but it
|
||||
// probably does
|
||||
|
||||
return false;
|
||||
remove_twitter_link($flink);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
// Twitter should return a status
|
||||
$status = json_decode($data);
|
||||
// Some other error happened, so we should probably
|
||||
// try to send again later.
|
||||
|
||||
if (empty($status)) {
|
||||
common_debug("Unexpected data returned by Twitter " .
|
||||
" API trying to send update for $twitter_user",
|
||||
__FILE__);
|
||||
$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);
|
||||
|
||||
// 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.
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($status)) {
|
||||
|
||||
// This could represent a failure posting,
|
||||
// or the Twitter API might just be behaving flakey.
|
||||
|
||||
$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);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notice crossed the great divide
|
||||
|
||||
$msg = sprintf('Twitter bridge posted notice %s to Twitter.',
|
||||
$notice->id);
|
||||
common_log(LOG_INFO, $msg);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
curl_close($ch);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, $options);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
return $response;
|
||||
if ($response === false) {
|
||||
$msg = curl_error($ch);
|
||||
$code = curl_errno($ch);
|
||||
throw new OAuthClientCurlException($msg, $code);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user