I wondered if someone can help?
I've purchased a web theme for a client but can't get the twitter widget working. It's probably something really simple but as I'm not a web developer I'm struggling to figure out what's preventing it form working.
Here's the webpage http://www.blackrocksearch.co.uk/new/ - the twitter feed should display in the footer. It works on the templates demo site but I notice in the item comments other customers having the same issue so think there could be a glitch somewhere.
Demo where it's working here:http://vasterad.com/themes/sensation/index.html
Here's the snippet of code from the twitter.php file which is apparently the only area I need to configure (I've left out the actual access token numbers for security):
<?php
/**
* Usage:
* Send the url you want to access url encoded in the url paramater, for example (This is with JS):
* /twitter-proxy.php?url='+encodeURIComponent('statuses/user_timeline.json?screen_name=MikeRogers0&count=2')
*/
// The tokens, keys and secrets from the app you created at https://dev.twitter.com/apps
$config = array(
'oauth_access_token' => 'token-here',
'oauth_access_token_secret' => 'token-here',
'consumer_key' => 'token-here',
'consumer_secret' => 'token-here',
'use_whitelist' => true, // If you want to only allow some requests to use this script.
'base_url' => 'http://api.twitter.com/1.1/'
);
/*
* Ok, no more config should really be needed. Yay!
*/
// We'll get the URL from $_GET[]. Make sure the url is url encoded, for example encodeURIComponent('statuses/user_timeline.json?screen_name=MikeRogers0&count=10&include_rts=false&exclude_replies=true')
if(!isset($_GET['url'])){
die('No URL set');
}
$url = $_GET['url'];
if($config['use_whitelist'] && !isset($whitelist[$url])){
die('URL is not authorised');
}
// Figure out the URL parmaters
$url_parts = parse_url($url);
parse_str($url_parts['query'], $url_arguments);
$full_url = $config['base_url'].$url; // Url with the query on it.
$base_url = $config['base_url'].$url_parts['path']; // Url with the query.
/**
* Code below from http://stackoverflow.com/questions/12916539/simplest-php-example-retrieving-user-timeline-with-twitter-api-version-1-1 by Rivers
* with a few modfications by Mike Rogers to support variables in the URL nicely
*/
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
// Set up the oauth Authorization array
$oauth = array(
'oauth_consumer_key' => $config['consumer_key'],
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $config['oauth_access_token'],
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
$base_info = buildBaseString($base_url, 'GET', array_merge($oauth, $url_arguments));
$composite_key = rawurlencode($config['consumer_secret']) . '&' . rawurlencode($config['oauth_access_token_secret']);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
// Make Requests
$header = array(
buildAuthorizationHeader($oauth),
'Expect:'
);
$options = array(
CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $full_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
);
$feed = curl_init();
curl_setopt_array($feed, $options);
$result = curl_exec($feed);
$info = curl_getinfo($feed);
curl_close($feed);
// Send suitable headers to the end user.
if(isset($info['content_type']) && isset($info['size_download'])){
header('Content-Type: '.$info['content_type']);
header('Content-Length: '.$info['size_download']);
}
echo($result);
?>
Hope someone can help!
By looking on your site on PHP file that doing a request to Twitter's response, it appears that your request needs to do a secure connection. So, my guesses are:
1. Connecting through https
Change your base_url key on $config variable to https.
$config = array(
'oauth_access_token' => 'token-here',
'oauth_access_token_secret' => 'token-here',
'consumer_key' => 'token-here',
'consumer_secret' => 'token-here',
'use_whitelist' => true,
'base_url' => 'https://api.twitter.com/1.1/' //was http://api.twitter.com/1.1/
);
2. Adding CA (Certificate Authority) cert file
In case my first guess doesn't resolve anything, adding CA cert on cURL request might help. First, get your own cacert.pem from here. Save it on some path you could recognize. Then simply set cURL option CURLOPT_SSL_VERIFYPEERto true and optionally you can also explicitly set CURLOPT_SSL_VERIFYHOST to its default value which is 2.
In example, according to your snippet, saving in a same path as your Twitter cURL PHP file.
$options = array(
CURLOPT_CAINFO => __DIR__ . '/cacert.pem', //or dirname(__FILE__) . '/cacert.pem' for PHP < 5.3
CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $full_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
);
As an option you can also predefine the cacert.pem in your php.ini configuration file. Just add/edit following line and don't forget about the path too
curl.cainfo = "some/path/cacert.pem"
Let me know
Related
Hi I'm trying to setup a PHP CURL call using OAuth1 authorization method.
I've tried with POSTMAN 1st, to generate the PHP code. I've completed it with the necessary datas
<?php
$conskey = 'XXXXXXX';
$conssec = 'XXXXXXX';
$nonce = mt_rand();
$timestamp = time();
$url = 'https://some-website/api/project/subproject';
$method = 'POST';
$oauth = new OAuth($conskey, $conssec, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_AUTHORIZATION);
$oauth->setNonce($nonce);
$oauth->setTimestamp($timestamp);
$signatureOAuth = $oauth->generateSignature($method, $url);
$curl = curl_init($url);
curl_setopt_array($curl, array(
CURLOPT_URL => $url.'?oauth_consumer_key='.$conskey.
'&oauth_signature_method=HMAC-SHA1&oauth_timestamp='.$timestamp.
'&oauth_nonce='.$nonce.
'&oauth_version=1.0&oauth_signature='.$signatureOAuth,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $jsonDatas,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
// THE COOKIE I WANNA GET
'Cookie: SSESSd4f3e89d4699e1d1a071aa37eab4fcEd=DWS4UqpaykI2y7q-HJXEzGN82AKHQYnWo5hbsqkAqiQ'
),
));
$result = curl_exec($curl);
curl_close($curl);
But I've noticed that there's the cookie in the CURLOPT_HTTPHEADER entry but I don't have any idea how POSTMAN generate this cookie.
Without this cookie or with a dumb string, the CURL response is always Invalid Signature
Postman is not generating cookies for you, and neither is curl/php. you either did some prior requests (usually GET to get cookies) requests to the website where you received some cookies, or gave the cookies to postman some other way.
since you're not showing us the real url, we can only speculate, but to take an example, here is how to get a session cookie for stackoverflow.com:
<?php
$ch=curl_init();
curl_setopt_array($ch,array(
CURLOPT_COOKIEFILE => "", // setting it to empty activates the curl cookie engine (its disabled by default.),
CURLOPT_URL => "https://stackoverflow.com/",
CURLOPT_RETURNTRANSFER => true,
));
$html=curl_exec($ch);
$cookies = (function($cookielist):array{
$cookies = array();
foreach($cookielist as $cookie_raw) {
$chunks = explode("\t", $cookie_raw);
//var_dump($chunks);
$cookie['domain'] = $chunks[0];
$cookie['secure'] = $chunks[1];
$cookie['path'] = $chunks[2];
$cookie['???todo_wtf_is_this'] = $chunks[3];
$cookie['expiration'] = $chunks[4];
$cookie['name'] = $chunks[5];
$cookie['value'] = $chunks[6];
$cookies[] = $cookie;
}
return $cookies;
})(curl_getinfo($ch, CURLINFO_COOKIELIST));
var_export($cookies);
prints something like
array (
0 =>
array (
'domain' => '#HttpOnly_.stackoverflow.com',
'secure' => 'TRUE',
'path' => '/',
'???todo_wtf_is_this' => 'FALSE',
'expiration' => '2682374400',
'name' => 'prov',
'value' => '9c06f038-9f70-bee8-2a64-b095656175d1',
),
)
which could be used like
// THE COOKIE I WANNA GENERATE
'Cookie: '. $cookies[0]["name"].'='.$cookies[0]["value"]
but this is very rarely done, usually you'd just use curl's built-in cookie engine to handle cookies automatically..
I trying to get streaming data from twitter, I found curl in twitter developer section to get streaming data
$ curl --request GET
--url 'https://api.twitter.com/1.1/search/tweets.json?q=nasa&result_type=popular'
--header 'authorization: OAuth oauth_consumer_key="consumer-key-for-app",
oauth_nonce="generated-nonce", oauth_signature="generated-signature",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="generated-timestamp",
oauth_token="access-token-for-authed-user", oauth_version="1.0"'
But i found how to use curl to get data at http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/ But I am getting
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
I checked my credential but could not solve ,problem persists: My code is below ::
$nonce = time();
$timestamp = time();
$oauth = array('oauth_callback' => 'https://localhost/twitter/curl.php',
'oauth_consumer_key' => 'bGLk7nhcMySEulFeRICCMdmtk',
'oauth_nonce' => $nonce,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => $timestamp,
'oauth_version' => '1.0');
function buildAuthorizationHeader($oauth){
$r = 'Authorization: OAuth '; //header prefix
$values = array(); //temporary key=value array
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\""; //encode key=value string
$r .= implode(', ', $values); //reassemble
return $r; //return full authorization header
}
$header = array( buildAuthorizationHeader($oauth), 'Expect:');
$options = array(CURLOPT_HTTPHEADER => $header, //use our authorization and expect header
CURLOPT_HEADER => false, //don't retrieve the header back from Twitter
CURLOPT_URL => 'https://api.twitter.com/1.1/search/tweets.json?q=nasa&result_type=popular', //the URI we're sending the request to
CURLOPT_POST => true, //this is going to be a POST - required
CURLOPT_RETURNTRANSFER => true, //return content as a string, don't echo out directly
CURLOPT_SSL_VERIFYPEER => false);
$ch = curl_init(); //get a channel
curl_setopt_array($ch, $options); //set options
$response = curl_exec($ch); //make the call
curl_close($ch); //hang up
echo $response;
I've created the following functions to access the twitter api and retrieve the latest tweet. It works just fine and I can display the latest tweet in the footer of my site but rather than happening on every page load I'd like to set up a cron job to fetch the latest tweet every hour.
I've not used the wp cron before so wondered if anyone could advise me on how best to do this?
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
function hs_tweets_fetch($screen_name = 'XXXXXXXXXXX', $count = 1) {
$config = array(
'oauth_access_token' => 'XXXXXXXXXXXXXX',
'oauth_access_token_secret' => 'XXXXXXXXXXXXXXX',
'consumer_key' => 'XXXXXXXXXXXXXXXXXXXXXX',
'consumer_secret' => 'XXXXXXXXXXXXXXXX',
'base_url' => 'https://api.twitter.com/1.1/'
);
$url = 'statuses/user_timeline.json?screen_name=' . $screen_name . '&count=' . $count;
$url_parts = parse_url($url);
parse_str($url_parts['query'], $url_arguments);
$full_url = $config['base_url'].$url; // Url with the query on it.
$base_url = $config['base_url'].$url_parts['path']; // Url without the query.
$oauth = array(
'oauth_consumer_key' => $config['consumer_key'],
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $config['oauth_access_token'],
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
$base_info = buildBaseString($base_url, 'GET', array_merge($oauth, $url_arguments));
$composite_key = rawurlencode($config['consumer_secret']) . '&' . rawurlencode($config['oauth_access_token_secret']);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(
buildAuthorizationHeader($oauth),
'Expect:'
);
$options = array(
CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $full_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
);
$feed = curl_init();
curl_setopt_array($feed, $options);
$result = curl_exec($feed);
$info = curl_getinfo($feed);
curl_close($feed);
if ($info['http_code'] == 200) {
$result = json_decode($result);
} else {
$result = false;
}
return $result;
}
You have to schedule hourly cron and than have to save tweets in your db. Cron to get tweets could be something like this.
if (!wp_next_scheduled('hs_tweets_fetch_cron'))
{
wp_schedule_event(time(), 'hourly', 'hs_tweets_fetch_cron');
}
add_action('hs_tweets_fetch_cron', 'hs_tweets_fetch');
function hs_tweets_fetch_cron()
{
1- // fetch the tweets
2- // Save/update the tweets in Wordpress options meta or custom table
}
And than display the tweets from database table in footer.
Instead of a cron for this type of work, I'll use the WordPress transient api.
Transient will make the same than à cron but differently. You can set an expiration and datas are store in the options table, If the transient name doesn't exists or if the expiration is over, then the function will create the transient with the data you need.
I have the following code, which works well apart from one issue, which is attaching the media_id to the final status update post. The media id just seems to be ignored and the text status is uploaded only. There is no error codes being output on either media upload request or status post.
Any ideas?
<?php
$oauth_access_token ="YOUR TOKEN";
$oauth_access_token_secret ="YOUR TOKEN SECRET";
$consumer_key ="YOUR KEY";
$consumer_secret ="YOUR SECRET";
//twitter api urls
$URLS=array(
"image"=>"https://upload.twitter.com/1.1/media/upload.json",
"status"=>"https://api.twitter.com/1.1/statuses/update.json");
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
function makeRequest($postfields,$url){
global $consumer_key;
global $consumer_secret;
global $oauth_access_token;
global $oauth_access_token_secret;
$oauth = array( 'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
$base_info = buildBaseString($url, 'POST', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
return $json;
}
//Upload image to twitter and get media_id
$file = file_get_contents(BASEPATH . '/images/myphoto.png');
$postfields=array("media_data"=>base64_encode($file));
$result=makeRequest($postfields,$URLS['image']);
$imageresult=json_decode($result);
$imageid=$imageresult->media_id;
//output results
print_r($imageresult);
//Send status update with media_id attached
$postfields=array(
"status"=>"test messsage with image",
"media_ids"=>$imageid);
//output results
$result=makeRequest($postfields,$URLS['status']);
$statusresult=json_decode($result);
print_r($statusresult);
?>
The media upload output looks complete
stdClass Object
(
[media_id] => 6.7933955975536E+17
[media_id_string] => 679339559755358208
[size] => 51719
[expires_after_secs] => 86400
[image] => stdClass Object
(
[image_type] => image/png
[w] => 187
[h] => 116
)
)
Try using media_id_string instead of media_id
I found the problem was with the windows hosting, it doesn't like certain curl requests in php as they don't always work. So I changed the hosting to Linux and it worked fine after that.
So. I'm trying to get all statuses from a list feed. To be more specific, this one https://dev.twitter.com/docs/api/1.1/get/lists/statuses
It's using the OAuth 1.0a, as far as I know.
My problem is, that I get an errorcode 32.
I'm using following code:
<?php function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
$url = "https://api.twitter.com/1.1/lists/statuses.json?slug=danskere-i-udlandet&owner_screen_name=d_fodbold&count=20";
$oauth_access_token = "29194047-Dzwsoo1KiQg69dbabt3nS2ezjjNzlbZdlKpLWsOOG";
$oauth_access_token_secret = "secret";
$consumer_key = "iCV8UbKjmq9LAw1XIvTQ";
$consumer_secret = "secret";
$oauth = array( 'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => md5(microtime()),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0');
$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
// Make Requests
$header = array(buildAuthorizationHeader($oauth));
$options = array( CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
var_dump($twitter_data);
exit();?>
I can't figure what the problem is there.
I hope some of you can.
I found out. The way the baseline was made, wasn't right.
The querystring has to be included in it, and sorted alphabetic.
I think there is a problem with your oauth_nonce. I don't think that md5(microtime()) is a good nonce generator. Try to do like the Twitter Developers documentation says about authorizing requests :
The oauth_nonce parameter is a unique token your application should
generate for each unique request. Twitter will use this value to
determine whether a request has been submitted multiple times. The
value for this request was generated by base64 encoding 32 bytes of
random data, and stripping out all non-word characters, but any
approach which produces a relatively random alphanumeric string should
be OK here.