I've been struggling to understand and find my way through the Uber API and their useless documentation.
I managed to put together this code in PHP which uses CURL to get an authorization_code code so I can further use that in other parts of my PHP page. For example, request a ride etc...
However, when I run my code, I get this error:
{"error": "invalid_grant"}
I searched high and low on Google and STO to see if i could find a solid answer to this but unfortunately nothing seems to give an straight forward answer and I'm stuck at this stage.
This is my code:
<?php
$fields_string = '';
$fields = array(
'client_secret' => '57KC5WGG3Ia455lc-i53e345345znXBB_0',
'client_id' => 'nnV4-_lsG9xl-SbAIQjIhwer234534534',
'grant_type' => 'authorization_code',
'redirect_uri' => "http://localhost:3000/auth/uber/callback",
'code' => $_GET['code']
);
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, "https://login.uber.com/oauth/v2/token");
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
$responseData = json_decode($result , TRUE);
$access_token = $responseData["access_token"];
echo "Access Token :" . $access_token ;
curl_close($ch);
?>
it might be worth mentioning that, the above code is all that I have in my php page. nothing else.
Questions:
Is there something that i am missing?
Do I need to do anything in my Uber developer dashboard?
Do I need to do anything else in my php page?
Any help or pointers that is laymen terms and make sense would be appreciated.
Possible solutions taken from: https://developer.uber.com/docs/riders/references/api/v2/token-post
You are using an invalid refresh_token. You can generate multiple access tokens, but you can only use the latest generated refresh_token.
You supplied an invalid code when exchanging an authorization code for an access_token.
Related
I need to add some functionality to my site to connect via REST to a provider and exchange data. I've used Postman for several years to test these APIs for myself and customers, but this is the first time I have tried to add the functionality to my site.
I've Googled numerous sites. I tried a few different things. First I tried the league/oauth2-client library. The requests went through without any errors, but all I received back was a response like this.
JSON response = {"status":"400","timeStamp":"2022-01-22T16:21:19+0000","error":{"errorId":"ea7bc74d-21ca-4503-92ad-3a76b05d7554","message":null,"code":"invalid_request","description":"Cannot generate token. Bad request","details":null}}
So I went to look at other examples. I found this nice and simple code from
UC San Diego Example for Client Credentials. I tried it and got the same type of results. "Cannot generate token. Bad request." For now, I like the simple option of the UCSD example if I can make it work.
As I said, I can successfully make this request and use the API all day long in Postman. So I know the Client ID, Client Secret, and URL are correct.
Unfortunately, I don't know how to troubleshoot this in PHP. I looked in the server log and I didn't find any errors. I tried to echo something out to see if I could see what was wrong, but I couldn't get the request to echo to the page. I tried using Fiddler to see if I could find the request with no luck.
Here's where I am right now. Any suggestions for what I am missing?
Thanks in advance for your help!
<?php
$token_url = "https://xxxx.xxxxx.com/services/api/oauth2/token";
$test_api_url = "https://xxxx.xxxxx.com/services/api/x/users/v2/employees/12345";
// client (application) credentials on xxxx.xxxxxx.com
$client_id = "xxxxxxxxxxx";
$client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$access_token = getAccessToken();
$resource = getResource($access_token);
echo "</br>access_token = " . $access_token;
echo "</br>resource = " . $resource;
// step A, B - single call with client credentials as the basic auth header
// will return access_token
function getAccessToken() {
global $token_url, $client_id, $client_secret;
$content = "grant_type=client_credentials";
$authorization = base64_encode("$client_id:$client_secret");
$header = array("Authorization: Basic {$authorization}","Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $token_url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $content
));
$response = curl_exec($curl);
curl_close($curl);
echo "</br>JSON response = " . $response;
return json_decode($response)->access_token;
}
// step B - with the returned access_token we can make as many calls as we want
function getResource($access_token) {
global $test_api_url;
$header = array("Authorization: Bearer {$access_token}");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $test_api_url,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response, true);
}
?>
So it seems that with a little bit of research and learning on my part the answer to my question was in Postman. Postman includes a feature that will translate your request into any number of code languages.
All I had to do was select the PHP option and copy and paste the results into my project. Boom, there you go. That was easy.
Here's a YouTube video showing how it works.
Postman: Import/Export and Generating Code Samples
I am working with an API that is documented here: https://cutt.ly/BygHsPV
The documentation is a bit thin, but I am trying to understand it the best I can. There will not be a developer from the creator of the API available before the middle of next week, and I was hoping to get stuff done before that.
Basically what I am trying to do is update the consent of the customer. As far as I can understand from the documentation under API -> Customer I need to send info through PUT to /customers/{customerId}. That object has an array called "communicationChoices".
Going into Objects -> CustomerUpdate I find "communicationChoices" which is specified as "Type: list of CommunicationChoiceRequest". That object looks like this:
{
"choice": true,
"typeCode": ""
}
Doing my best do understand this, I have made this function:
function update_customer_consent() {
global $userPhone, $username, $password;
// Use phone number to get correct user
$url = 'https://apiurlredacted.com/api/v1/customers/' . $userPhone .'?customeridtype=MOBILE';
// Initiate cURL.
$ch = curl_init( $url );
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt( $ch, CURLOPT_USERPWD, $username . ":" . $password );
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Data to send
$data = [
"communicationChoices" => [
"communicationChoiceRequest" => [
"choice" => true,
"typeCode" => "SMS"
]
]
];
$json_payload = json_encode($data);
print_r($json_payload);
// Set other options
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($json_payload)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
// Execute the cURL request
$response = curl_exec($ch);
// Check for errors.
if( curl_errno( $ch ) ) :
// If an error occured, throw an Exception.
throw new Exception( curl_error( $ch ) );
endif;
if (!$response)
{
return false;
} else {
// Decode JSON
$obj = json_decode( $response );
}
print_r($response);
}
I understand that this is very hard to debug without knowing what is going on within the API and with limited documentation, but I figured asking here was worth a shot anyway.
Basically, $json_payload seems to be a perfectly fine JSON object. The response from the API however, is an error code that means unknown error. So I must be doing something wrong. Maybe someone has more experience with APIs and such documentation and can see what I should really be sending and how.
Any help or guidance will be highly appreciated!
before you test your code, you can use the form provided on the API Documentation.
when you navigate to API > Customers > /customers/{customerId} (GET), you will see a form on the right side of the page (scroll up). you need to provide the required values on the form then hit Submit button. you will surely get a valid data for communicationChoices based on the result from the Response Text section below the Submit button.
now, follow the data structure of communicationChoices object that you get from the result and try the same on API > Customers > /customers/{customerId} (PUT) form.
using the API forms, you may be able to instantly see a success or error from your input (data structure), then translate it to your code.
I have a Vimeo PRO account.
I have protected videos uploaded.
Videos are also set to ONLY be embeddable on my domains (set in the video settings)
I am -not- grasping how to use their examples (sorry, for me the examples do not include real working samples for me,..or at least how to implement them to understand.. so I'm hoping to get some help)
Not clear on all the OAuth2, Oembed... authentication stuff either.. which I believe is where my problem lies.
I was following this gitHub example:
https://github.com/vimeo/vimeo-api-examples/blob/master/oembed/php-example.php
(looks to be pretty old?)
I'm looking to get JSON data returned for a video when an ID is passed along.
I was/am under the impression that I need to 'authenticate' before I can get my response/return data?
Is this best done in the CURL header or something?
Can someone guide me a bit more? (shouldnt be this hard!) haha..
Here is my code:
$video_endpoint = 'https://api.vimeo.com/videos/';
$video_url = '171811266';
//JSON url
//$json_url = $video_endpoint . '.json?url=' . rawurlencode($video_url);
//this fixes the cURL approach
$json_url = $video_endpoint . rawurlencode($video_url);
// Curl helper function
function curl_get($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
//curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization : bearer xxxxxx'));
$return = curl_exec($curl);
curl_close($curl);
return $return;
}
$vimeoJSON = json_decode((curl_get($json_url)));
var_dump($vimeoJSON);
And I get this response:
object(stdClass)#1 (1) { ["error"]=> string(52) "You must provide a valid authenticated access token." }
questions are:
1.) Is this even a valid approach? (assuming I just need to append some lines of code to the CURL header to send my auth over before getting a response?)
2.) How do I update my CURL snippet to work with VIEMO authentication?
I'm trying to keep this as CLEAN/SIMPLE as I can (for the JSON call/return portion)..
Any guidance is appreciated.
Thanks
update:
this code does NOT work:
$access_token = 'xxx';
$video_endpoint = 'https://api.vimeo.com/videos/';
$video_url = '171811266';
$json_url = $video_endpoint . '.json?url=' . rawurlencode($video_url);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $json_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Bearer ".$access_token
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
The video I want to use is located here:
https://vimeo.com/171811266/5822169b48
IT IS A PRIVATE VIDEO. (not sure you'll be able to see it)..
When I use the latest version of the code posted above.. I get this response:
{"error":"The requested video could not be found"}
Is this because its a PRIVATE video?
(actually I just set the video to be able to be viewed by anyone.. and I still got the same error/response) (not found)
If so.. what is the fix to use MY videos.. that are set to private... but use them on my site/domain still?
===========================================================================
FINAL UPDATE:
Trying to use the code in the readme example:
https://github.com/vimeo/vimeo.php
Trying to use (un-successfully) the LIB #Dashron pointed me too.. I cant even seem to get the basics to work from the GIT Page:
Code:
//project vars
$client_id = 'xxxx';
$client_secret = 'xxx';
$access_token = 'xxx';
$redirect_uri = 'http://domain.com/file.php'; //where do I redirect them back to? the page where I have the embeded video at?
// scope is an array of permissions your token needs to access. You can read more at https://developer.vimeo.com/api/authentication#scopes
$scopes = Array('public', 'private');
$state = 'Ldhg0478y';
require("Vimeo/autoload.php");
$lib = new Vimeo\Vimeo($client_id, $client_secret);
// build a link to Vimeo so your users can authorize your app. //whatever that means and is for?
$url = $lib->buildAuthorizationEndpoint($redirect_uri, $scopes, $state);
// redirect_uri must be provided, and must match your configured uri
$token = $lib->accessToken(code, redirect_uri);
// usable access token
var_dump($token['body']['access_token']);
// accepted scopes
var_dump($token['body']['scope']);
// use the token
$lib->setToken($token['body']['access_token']);
I get this error message:
Parse error: syntax error, unexpected Fatal error: Class 'Vimeo\Vimeo' not found in /usr/www/users/aaemorg/aaem.org/video/vimeo_lib.php
Seems like its not creating instantiating my $lib object/class??
(I know I'm not great at high level PHP class/code... but this absurdly hard just to get a JSON response for video I own to embed (again) on a site I own as well)
Any direction would be appreciated?
======================================================================
Update: "what worked for me"..
I am appreciate the link to the 'official' library.. but the readme examples just didnt work for me...
To keep things nice and easy for others who may be new to the Vimeo API stuff as well.. here is a quick and dirty, simple code sample to get you up and running:
<?
//include offifial library
require("Vimeo/autoload.php");
$client_id = 'xxx';
$client_secret = 'xxx';
$access_token = 'xxx';
$video_id = 'xxx';
$lib = new Vimeo\Vimeo($client_id, $client_secret, $access_token);
$video_response = $lib->request('/videos/'.$video_id);
//dont really need this, but included in case there is some data you need to display
$token_response = $lib->clientCredentials();
//example of parsing out specific data from the array returned
//name/title
echo $video_response['body']['name'] . '<br><br>';
?>
The link you provided is very, very old. It is actually part of a different API, and no longer relevant.
The Library you should be using is located here: https://github.com/vimeo/vimeo.php with many examples in the readme, and the examples directory!
Below code works for me
Please follow this step before
Under video settings : General->privacy, Change Who can watch select box to Anyone.
$url = 'https://api.vimeo.com/videos/388591356';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$headers = array();
$headers[] = "Content-Type: application/x-www-form-urlencoded";
$headers[] = "Accept: application/json";
$headers[] = "Authorization: Bearer 969329f9b5b3882d74d1b39297528242";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
$final_result = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $result), true );
echo "<pre>";
print_r($final_result);
I used the FQL until a few days ago to retrieve Facebook data, but I noticed that it will be discontinued in about 1 year so I upgraded to Graph API. But am I using it correctly? Will this method work still next year? I am still using a
facebook.php,
base_facebook.php and
fb_ca_chain_bundle.crt
from 2011 but then again I only need these functions.
Here's my code, thanks for any advice you can give me :)
function get_content($URL){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URL);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$access_token = $facebook->getAccessToken();
$data = get_content("https://graph.facebook.com/" . $facebook_id . "/?fields=name,first_name,last_name,email&access_token=".$access_token);
$data_array = json_decode($data, true);
$new_array = array(
"uid" => $data_array['id'],
"name" => $data_array['name'],
"first_name" => $data_array['first_name'],
"last_name" => $data_array['last_name'],
"email" => $data_array['email']
);
That looks perfectly correct!
The only improvement to that code would be to add the API version number to the call.
So, use https://graph.facebook.com/v2.4/
$data = get_content("https://graph.facebook.com/v2.4/**" . $facebook_id . "/?fields=name,first_name,last_name,email&access_token=".$access_token);
That way, you'll not be affected by any changes until at least July 2017!
You might want to catch any connection or HTTP errors returned.
Some of the HTTP errors are documented here.
You can use the Graph API explorer for making test API calls and verifying your requests.
PHP code:
$fields_string = "";
foreach ($postingfields as $key=>$value) {
$fields_string .= $key . '=' . urlencode($value) . '&';
}
$fields_string = rtrim($fields_string,'&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$client_url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$response = curl_getinfo( $ch );
curl_close($ch);
$client_url php variable holds the value: https://pcloudtest.com/Default.aspx?cid=99938
$fields_string php variable holds the value: &sid=30&title=Mr&firstname=Charles&surname=Smith
The destination server has been set up to respond with the following HTML:
When I debug (send info to a separate txt file in linux) the value of $result is:
<URL>https://pcloudtest.com/Default.aspx?cid=99938</URL>
ie this is what the destination server is claiming has been sent to them from my end.
In other words, the $client_url is all that is being posted, and not the rest of it (ie the $fields_string) and the full URL that should've been posted should read:
https://pcloudtest.com/Default.aspx?cid=99938&sid=30&title=Mr&firstname=Charles&surname=Smith
I have tried everything I can to figure out why the php curl functions are apparently sending out a shortened URL, ie up to the first occurrence of an ampersand. The code logic I have above has not changed in months and is working for other destination servers.
I might add that the other destination servers where this logic has no issues are http: sites not https:. But I have been reassured by the tech guys on the other end that it definitely has nothing to do with posting to a https site.
Please help. I hope I have outlined my issue clearly enough, and if not, please advise as to more info I can provide.