I'm trying to work with the examples on the Twitter dev site but can't seem to get to the same signature as they have.
I am trying to complete step 3 on https://dev.twitter.com/docs/auth/implementing-sign-twitter because I am getting an error "Invalid or expired token" but I know it isn't because I've only just been given it, so it must be something wrong with my data packet.
The code I am using to try and generate this is:
// testing bit
$oauth = array(
'oauth_consumer_key'=>'cChZNFj6T5R0TigYB9yd1w',
'oauth_nonce'=>'a9900fe68e2573b27a37f10fbad6a755',
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>'1318467427',
'oauth_token'=>'NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0',
'oauth_version'=>'1.0'
);
$this->o_secret = 'LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE';
$this->c_secret = 'kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw';
ksort($oauth);
$string = rawurlencode(http_build_query($oauth));
$new_string = strtoupper($http_method).'&'.rawurlencode($main_url[0]).'&'.$string;
// The request_token request doesn't need a o_secret because it doesn't have one!
$sign_key = strstr($fullurl,'request_token') ? $this->c_secret.'&' : $this->c_secret.'&'.$this->o_secret;
echo urlencode(base64_encode(hash_hmac('sha1',$new_string,$sign_key,true)));exit;
And I'm assuming that the keys listed on this page are in fact correct: https://dev.twitter.com/docs/auth/creating-signature. So in that case the signature should be 39cipBtIOHEEnybAR4sATQTpl2I%3D.
If you can spot what I'm missing that would be great.
Your consumer secret and token secret are incorrect for the page you reference. If you look further up the page you can see that they should be:
Consumer secret: L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Token secret: veNRnAWe6inFuo8o2u8SLLZLjolYDmDP7SzL0YfYI
Also in Step 3 you need to include the oauth_verifier in the list of parameters when calculating your signature base string.
I'm not familiar with PHP so I haven't checked your code to calculate the signature.
This code has now worked - I will tidy it up from there :)
// This function is to help work out step 3 in the process and why it is failing
public function testSignature(){
// testing bit
$oauth = array(
'oauth_consumer_key'=>'cChZNFj6T5R0TigYB9yd1w',
'oauth_nonce'=>'a9900fe68e2573b27a37f10fbad6a755',
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>'1318467427',
'oauth_token'=>'NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0',
'oauth_version'=>'1.0'
);
$this->o_secret = 'LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE';
$this->c_secret = 'kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw';
ksort($oauth);
$string = http_build_query($oauth);
$new_string = strtoupper($http_method).'&'.$main_url[0].'&'.$string;
$new_string = 'POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521';
// The request_token request doesn't need a o_secret because it doesn't have one!
$sign_key = $this->c_secret.'&'.$this->o_secret;
echo 'Should be: tnnArxj06cWHq44gCs1OSKk/jLY=<br>';
echo 'We get: '.base64_encode(hash_hmac('sha1',$new_string,$sign_key,true));
exit;
}
you want to access token from twitter and sign in implementation you can see in this example.
1) http://www.codexworld.com/login-with-twitter-using-php/
and this one for timeline tweets
2) http://www.codexworld.com/create-custom-twitter-widget-using-php/
may be this help you .
Related
I am looking for a little assistance on listing available phone numbers for purchase using Twilios API and PHP for their 5.X API Verison. Below is the error I get and the PHP im using. Im sure im just overlooking something:
PHP Notice: Trying to get property of non-object in /twilio-php-app/findnumbers.php on line 16
PHP Warning: Invalid argument supplied for foreach() in /twilio-php-app/findnumbers.php on line 16
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once 'vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "Axxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$token = "removed";
$client = new Client($sid, $token);
$numbers = $client->availablePhoneNumbers('US')->local->read(
array("areaCode" => "513")
);
foreach($numbers->availablephonenumbers as $number) {
echo $number->phone_number;
}
If I echo $numbers I find it is an array. Here is the raw output where I just want to get the "phone_number": "xxxxxx" output; minus the "phone_number": part.
output of array Screenshot
Adding to this, if I run the PHP as the following; I get single number outputs
$numbers = $client->availablePhoneNumbers('US')->local->read(
array("areaCode" => "513")
);
echo $numbers[1]->phoneNumber;
Changing the value of [1] to [2] grabs the next phone number. How can I loop this?
Might not be done 100% correct but I found a solution that increases the count of the array based on count and stacks the numbers nicely.
Sharing this in case anyone else ever comes across this and needs help; this does exactly what its intended to.... Search the twilio databse for available numbers to purchase, based on criteria
<?php
// Get the PHP helper library from https://twilio.com/docs/libraries/php
require_once 'vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "your_SID";
$token = "Your_Token";
$client = new Client($sid, $token);
$numbers = $client->availablePhoneNumbers('US')->local->read(
array("areaCode" => "513")
);
for ($i = 0; $i < count($numbers); ++$i) {
print $numbers[$i]->phoneNumber . "\n";
}
Just an observation, but you are already using the availablePhoneNumbers method on $client when you say $numbers = $client->availablePhoneNumbers...
Perhaps, in the foreach, you just need to reference $numbers and not $numbers->availablephonenumbers?
Using the code given from Packagist (https://packagist.org/packages/patreon/patreon?q=&p=6), I am unable to get the expected results. My code now logs the user in, and returns their data (which I can view via var_dump), but I'm having issues actually reading it.
According to the Patreon API documentation, the data received from the API is automatically set as an array, unless specified otherwise. I'm running the exact code from their website but their API is returning an object, and I'm not sure how to read the user's data and pledge information from it. I've tried setting the return data as an array or json without any luck. I'm just getting this jumbled mess when I convert the API response into an array.
Screenshot - https://i.gyazo.com/3d19f9422c971ce6e082486cd01b0b92.png
require_once __DIR__.'/vendor/autoload.php';
use Patreon\API;
use Patreon\OAuth;
$client_id = 'removed';
$client_secret = 'removed';
$redirect_uri = "https://s.com/redirect";
$href = 'https://www.patreon.com/oauth2/authorize?response_type=code&client_id=' . $client_id . '&redirect_uri=' . urlencode($redirect_uri);
$state = array();
$state['final_page'] = 'http://s.com/thanks.php?item=gold';
$state_parameters = '&state=' . urlencode( base64_encode( json_encode( $state ) ) );
$href .= $state_parameters;
$scope_parameters = '&scope=identity%20identity'.urlencode('[email]');
$href .= $scope_parameters;
echo 'Click here to login via Patreon';
if (isset($_GET['code']))
{
$oauth_client = new OAuth($client_id, $client_secret);
$tokens = $oauth_client->get_tokens($_GET['code'], $redirect_uri);
$access_token = $tokens['access_token'];
$refresh_token = $tokens['refresh_token'];
$api_client = new API($access_token);
$campaign_response = $api_client->fetch_campaign();
$patron = $api_client->fetch_user();
$patron = (array)$patron;
die(var_dump($patron));
}
I want to be able to view the user's data and pledge information. I've tried things such as $patron->data->first_name, $patron['data']['first_name'], etc. which have all thrown errors about the index of the array not being found.
You've probably already figured something out but I ran into the same thing and thought I'd share a solution here.
The JSONAPIResource object that the patreon library returns has a few specific methods that can return the individual pieces of data in a readable format.
import patreon
from pprint import pprint
access_token = <YOUR TOKEN HERE> # Replace with your creator access token
api_client = patreon.API(access_token)
campaign_response = api_client.fetch_campaign()
campaign = campaign_response.data()[0]
pprint(campaign.id()) # The campaign ID (or whatever object you are retrieving)
pprint(campaign.type()) # Campaign, in this case
pprint(campaign.attributes()) # This is most of the data you want
pprint(campaign.attribute('patron_count')) # get a specific attribute
pprint(campaign.relationships()) # related entities like 'creator' 'goals' and 'rewards'
pprint(campaign.relationship('goals'))
pprint(campaign.relationship_info())
# This last one one ends up returning another JSONAPIResource object with it's own method: .resource() that returns a list of more objects
# for example, to print the campaign's first goal you could use:
pprint( campaign.relationship_info('goals').resource()[0].attributes() )
Hope that helps someone!
I've been trying to post an image with a simple message onto twitter using PHP and twitteroauth.php.
However, every time I run my code, I only get the $tweetMessage published on the twitter feed without any image.
I searched and searched and read their own documentation but don't even get me started on their own documentation! its like someone who's had a sleepwalk was writing their documentation. Just a bunch of jargon..
And most of the information on STO is either outdated or pointing to a library!
I do not want to use any library as I will have to try to learn someone else's code as well and Surely twitter would allow publishing photo's using their own API without the use of any third party Library?!
Any way, This is my full code:
// Include twitteroauth
require_once('inc/twitteroauth.php');
// Set keys
$consumerKey = 'xxxxxxxxxxxxxxxxxxx';
$consumerSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$accessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$accessTokenSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// Create object
$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);
// Set status message
$tweetMessage = 'This is a tweet to my Twitter account via PHP.';
$image_path="https://www.google.co.uk/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
$handle = fopen($image_path,'rb');
$image = fread($handle,filesize($image_path));
fclose($handle);
// Check for 140 characters
if(strlen($tweetMessage) <= 140)
{
// Post the status message
$tweet->post('statuses/update', array('media[]' => "{$image};type=image/jpeg;filename={$image_path}", 'status' => $tweetMessage));
}
Could someone please advise on this issue?
Thanks in advance.
EDIT:
I've changed my code to the following and I get this error:
{"errors":[{"code":195,"message":"Missing or invalid url parameter."}]}
But I'm sure the image is on the specified URL/directory!
This is the code:
require_once 'inc/twitteroauth.php';
define("CONSUMER_KEY", "xxxxxxxxxxxxxxxxx");
define("CONSUMER_SECRET", "xxxxxxxxxxxxxxxxxxxxxxxxxx");
define("OAUTH_TOKEN", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
define("OAUTH_SECRET", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_SECRET);
$content = $connection->get('images/sign-in-with-twitter-l.png');
$image = 'images/sign-in-with-twitter-l.png';
$status_message = 'Attaching an image to a tweet';
$status = $connection->post('statuses/update_with_media', array('status' => $status_message, 'media[]' => file_get_contents($image)));
echo json_encode($status);
Any idea why this error is being shown?
Uploading media to Twitter is slightly complicated. Essentially, it's a three stage process.
Upload the photo to Twitter.
Receive a media_id back from Twitter.
Post your status and media_id to Twitter.
This is described in great detail at https://dev.twitter.com/rest/reference/post/media/upload
Generally speaking, it is easier for use to use a library like CodeBird as they've already done the hard work of finding all the edge cases.
But, assuming you don't want to do that...
POST the image to /1.1/media/upload.json
Receive back some JSON like
{
"media_id": 553656900508606464,
"media_id_string": "553656900508606464",
"size": 998865,
"image": {
"w": 2234,
"h": 1873,
"image_type": "image/jpeg"
}
}
* Use that media_id_string when you post the status. e.g.
tweet->post('statuses/update', array('media_ids' => $media_id_string, 'status' => $tweetMessage));
Hopefully that gives you enough to understand what's going on.
I solved it like this:
$tweet_img = 'Path/to/image';
$handle = fopen($tweet_img,'rb');
$image = fread($handle,filesize($tweet_img));
fclose($handle);
$parameters = array('media[]' => "{$image};type=image/jpeg;filename={$tweet_img}",'status' => 'Picture time');
$returnT = $connection->post('statuses/update_with_media', $parameters, true);
Horrible twitter API documentation needs improving!! it needs to be written by humans as opposed to a bunch of sleepwalking zombies!!!
This is a very frustrating situation that they put us in when we try to use their API...
They either need stop their API support and remove it all from the public or simply improve their documentation and write it for the public and not just for their own use using jargon words.
Any way, the above code works just fine using the latest twitteroauth
I hope this helps others in my situation.
I feel like i wasted 5 hours for something that should be clear and mentioned in plain English on their site!!!
Rant and Answer over & good luck.. :)
I'm using a simple PHP script to verify Android order to parse download for the customer.
$receipt = $_GET['purchaseData'];
$billInfo = json_decode($receipt,true);
$signature = $_GET['dataSignature'];
$public_key_base64 = "xxxxxxxxxxxxxxxx";
$key = "-----BEGIN PUBLIC KEY-----\n".
chunk_split($public_key_base64, 64,"\n").
'-----END PUBLIC KEY-----';
$key = openssl_get_publickey($key);
$signature = base64_decode($signature);
//$result = openssl_verify($billInfo, $signature, $key);
$result = openssl_verify($receipt, $signature, $key);
if (0 === $result) {
echo "0";
} else if (1 !== $result) {
echo "1";
} else {
echo "Hello World!";
}
//added the var_dump($result); as asked by A-2-A
var_dump($result);
result is 0int(0)
I made a real order through the App after I published it and when trying to validate the order I get "0" as result.
I tried direct HTTP access
https://domain.com/thankyou.php?purchaseData={"packageName":"com.example.app","orderId":"GPA.1234-5678-1234-98608","productId":"product","developerPayload":"mypurchasetoken","purchaseTime":1455346586453,"purchaseState":0,"developerPayload":"mypurchasetoken","purchaseToken":"ggedobflmccnemedgplmodhp...."}&dataSignature=gwmBf...
I'm keeping the first of the question because my result is still a guess. After further investigation I think it's the signature not being read in a nice clean way as sent by google.
The signature=gwmBfgGudpG5iPp3L0OnepNlx while the browser is reading it as ƒ ~®v‘¹ˆúw
How is it possible to let it be read in the right way?
To verify the signature you want to make sure of the following:
INAPP_PURCHASE_DATA is not mutated in any way. Any encoding or escaping changes will result in a invalid verification. The best way to ensure it gets to your server intact is to base64 encoded it.
INAPP_DATA_SIGNATURE also must remain intact, it should already base64 encoded so sending that to your server should not be a problem.
openssl_verify expects both data and signature arguments to be in their raw state, so base64 decode before verifying.
It also takes signature_alg as the last argument, in this case sha1WithRSAEncryption should work as should the default, but if in doubt try a few other sha1 algorithms to see which ones work.
My best guess why it's not working for you right now is that you're not receiving the INAPP_PURCHASE_DATA on your server in the same condition that it was received on the app. This Stackoverflow question had the same problem.
I built a PHP file with the sole purpose of hiding the API keys for Google Search, but part of the file_get_contents() always echo angular.callbacks._0_({ instead of angular.callbacks._0({
This small change makes the rest of the response worthless as Angular throws Uncaught TypeError: angular.callbacks._0_ is not a function. Although the workaround does works flawlessly, I would like to know if someone found the root of this issue or a better solution that is strictly PHP (no curl or any other package.)
search.php
<?php // Created by Deovandski on 2/14/2016
header('Content-type: application/json');
# Setup Base URL and array for Parameters
$host = 'https://www.googleapis.com/customsearch/v1?';
$queries = array();
$queries['cx'] = "XXX";// CSE KEY
$queries['key'] = "XXX"; // API KEY
# Setup possible incoming params
if (isset($_GET['search_term'])) $queries['q'] = $_GET['search_term'];
if (isset($_GET['result_count'])) $queries['result_count'] = $_GET['result_count'];
if (isset($_GET['callback'])) $queries['callback'] = $_GET['callback'];
# Build query and Final URL
$queriesURL = http_build_query($queries) . "\n";
$finalURL = $host.$queriesURL;
echo $finalURL;
/* echo $finalURL output (I only edited the keys out):
https://www.googleapis.com/customsearch/v1?cx=XXX&key=XXX&q=Hatsune+Miku&result_count=10&callback=angular.callbacks._0
*/
// Setup Response
$response = file_get_contents($finalURL);
// workaround
$fixedResponse = str_replace("angular.callbacks._0_", "angular.callbacks._0", $response);
echo $fixedResponse;
?>
This is part of a correct Google API response:
// API callback
angular.callbacks._0({
"kind": "customsearch#search",
"url": {
"type": "application/json",
"template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&cref={cref?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
},
I put up a live version of this issue that can be seen on my FTP server. The PHP file can be viewed through this link (AngularJS parameters included on it).
The problem is the escape sequences \n. Which is passed as part of the request. And which is interpreted as space and as part of the callback function name and replaced by the side of the API to underline.
To understand just try this option and look at the result:
$queriesURL = http_build_query($queries) . "\n" . "after";
So just take away a newline.