I have problem with downloading file from google drive using php api. I managed to upload file to google drive in folder and $service->files->insert returns to me File Resource which has attribute downloadUrl but when I redirect to that url, it does not work. I get 401 error. Why is this happening? What do I need to do make this work?
Here's code:
<?php
require_once 'vendor/autoload.php';
session_start();
$client_id = 'xxx';
$client_secret = 'yyy';
$redirect_uri = 'http://localhost/GoogleDrive/code.php';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/drive");
$service = new Google_Service_Drive($client);
$authUrl = $client->createAuthUrl();
header("Location: $authUrl");
and code.php
require_once 'vendor/autoload.php';
session_start();
$client_id = 'xxx';
$client_secret = 'yyy';
$redirect_uri = 'http://localhost/GoogleDrivePayload/code.php';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setApprovalPrompt('force');
$client->addScope("https://www.googleapis.com/auth/drive");
$service = new Google_Service_Drive($client);
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['upload_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['upload_token']) && $_SESSION['upload_token']) {
$client->setAccessToken($_SESSION['upload_token']);
if ($client->isAccessTokenExpired()) {
unset($_SESSION['upload_token']);
}
}
if ($client->getAccessToken()) {
$file = new Google_Service_Drive_DriveFile();
$file->setTitle("hello.exe");
$file->setDescription("LALALALALAL");
$file->setMimeType('application/x-msdos-program');
$parent = new Google_Service_Drive_ParentReference();
$parent->setId("zzz");
$file->setParents(array($parent));
$data = file_get_contents('hello.exe');
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => 'application/x-msdos-program',
'uploadType' => 'multipart',
"visibility" => "DEFAULT"
));
header("Location: " . $createdFile->downloadUrl);
}
downloadUrl is exactly what it says, ie. the URL your PHP app can use to fetch the file. You would almost never redirect a browser to that URL, and if you did (you probably really don't want to), you'll need append a valid access token to the URL to fix the 401.
Related
I am trying to get analytics data can someone help me, below are the ways I tried but I am getting 500 internal server.
<?php
require_once realpath(dirname(__FILE__) . '/google-api-php-client-master/src/Google/autoload.php');
session_start();
$client = new Google_Client();
$client->setApplicationName("meme");
$client->setDeveloperKey('my app key here');
$service = new Google_Service_Analytics($client);
$projectId = '103785255';
$from = '2016-01-18'; // 2 days
$to = date('Y-m-d'); // today
$metrics = 'ga:pageviews';
$dimensions = 'ga:date,ga:year,ga:month,ga:day';
$data = $service->data_ga->get('ga:'.$projectId, $from, $to, $metrics, array('dimensions' => $dimensions));
print_r($data);
?>
Second method with oauth-2.0 authentication
<?php
require_once realpath(dirname(__FILE__) . '/google-api-php-client-master/src/Google/autoload.php');
session_start();
$client_id = 'my client id .apps.googleusercontent.com';
$client_secret = 'my client secret';
$redirect_uri = 'redirect uri';
$client = new Google_Client();
$client->setApplicationName("meme");
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri($redirect_uri);
$client->setAccessType("offline");
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);print_r($client);exit;
$_SESSION['token'] = $client->getAccessToken();
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
if (!$client->getAccessToken() && !$_SESSION['token']) {
$authUrl = $client->createAuthUrl();
print "<div><a class='login' href='$authUrl'>Connect Me!</a></div>";
}
if($_SESSION['token']){
$client->setAccessToken($_SESSION['token']);
$service = new Google_Service_Analytics($client);
$projectId = '103785255';
$_params[] = 'pageviews';
$from = '2016-01-18'; // 2 days
$to = date('Y-m-d'); // today
$metrics = 'ga:pageviews';
$dimensions = 'ga:date,ga:year,ga:month,ga:day';
$data = $service->data_ga->get('ga:'.$projectId, $from, $to, $metrics, array('dimensions' => $dimensions));
foreach($data['totalsForAllResults'] as $row) {
echo $row;
}
}
?>
If you see I have placed a print statement after $client->authenticate($_GET['code']); where I am getting 500 internal server error If I print the code before authenticate method it is printing, facing issue while calling $client->authenticate($_GET['code']). Even followed the below links and endup with the same issues
Google PHP client won't authenticate code, invalid_request
http://www.daimto.com/google-oauth2-php/
I am trying to upload files to google drive using below code
require_once 'google-api-php-client-master/src/google/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->addScope('https://www.googleapis.com/auth/drive');
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
$client->setAccessToken($_SESSION['access_token']);
/*$drive_service = new Google_Service_Drive($client);
$files_list = $drive_service->files->listFiles(array())->getItems();
echo json_encode($files_list);*/
$service = new Google_Service_Drive($client);
$file = new Google_Service_Drive_DriveFile();
$file->setTitle("test");
$file->setMimeType('application/vnd.google-apps.folder');
$createdFile = $service->files->insert($file, array(
'mimeType' => 'application/vnd.google-apps.folder',
'uploadType' => 'multipart'
));
echo "===".$fileId = $createdFile->id;
}
else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/google/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
and it is giving me insufficient permissions error.
Am i missing something?
I tried using Service account and it worked fine, Is Service account required to upload files using Google Drive API?
I had a problem on making the Google Drive API work. I want to allow public user to search on my file list and upload files to my Google Drive.
I created an API key on my developer console and added it to the following script and try to read a list of my files, but didn't work. It returned "500 Internal Server Error". Do I miss anything?
require_once 'google-api-php-client/src/Google/autoload.php';
$client = new Google_Client();
$client->setDeveloperKey("MY_API_KEY");
$client->addScope("https://www.googleapis.com/auth/drive");
$dr_service = new Google_Service_Drive($client);
$dr_results = $dr_service->files->listFiles(array('maxResults' => 10))
I tried to use ClientID (see the following code) and it works but I don't want to prompt the user to login to their google account and I want them to do everything on my account. Or how can I call the oauth with my account without prompting the user?
session_start();
require_once 'google-api-php-client/src/Google/autoload.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('MY_CLIENT_ID');
$client->setClientSecret('MY_CLIENT_SECRET');
$client->setRedirectUri('MY_URL');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$authUrl = $client->createAuthUrl();
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://MY_URL');
}
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
if (isset($_SESSION['token'])) {
print "<a class='logout' href='".$_SERVER['PHP_SELF']."?logout=1'>LogOut</a><br>";
$client->setAccessToken($_SESSION['token']);
$service = new Google_Service_Drive($client);
var_dump($service->files->ListFiles());
}
download the files from here google drive client in a folder google_drive.Then try this code
include the three files .
require 'google_drive/Google_Client.php';
require 'google_drive/contrib/Google_DriveService.php';
require 'google_drive/socialmedia_oauth_connect.php';
create new object of the classess.
$client_gd = new Google_Client();
$service = new Google_DriveService($client_gd);
$file=new Google_DriveFile();
set access token
if(isset($_GET['code']))
{
$authCode = $_REQUEST['code'];
$accessToken = $client_gd->authenticate($authCode);
$_SESSION['access_token_gd']=$accessToken;
$client_gd->setAccessToken($accessToken);
$about = $service->about->get();
$user=$about['permissionId'];
$_SESSION['gd_user']=$user;
$_SESSION['user_info_gd']=$about;
header('location:'.HOME.'?index_gd=1');
}
authenticate with google drive
$authUrl = $client_gd->createAuthUrl();
//$clientid = $gdsettings->gdclient_id;
// $clientsec = $gdsettings->gdclient_secret;
$redirecturi = HOME.'index.php';
$oauth = new socialmedia_oauth_connect();
$oauth->provider="Google";
global $apiConfig;
$oauth->client_id = $apiConfig['oauth2_client_id'];
$oauth->client_secret = $apiConfig['oauth2_client_secret'];
$oauth->scope="https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/";
$oauth->redirect_uri = $apiConfig['oauth2_redirect_uri'];
$oauth->approval_prompt = "force";
$oauth->Initialize();
$oauth->Authorize();
get the files
$accessToken=$_SESSION['access_token_gd'];
$client_gd->setAccessToken($accessToken);
//print_r($client_gd->getAccessToken());
//List of files
$arr = array();
$files = $service->files->listFiles();
$about = $service->about->get();
$user=$about['permissionId'];
//$_SESSION['gd_user']=$user;
//$_SESSION['user_info_gd']=$about;
$drivefiles = $files["items"];
foreach($drivefiles as $divefl )
{
echo $divefl['title'];
}
here is the full description you can read google drive client integration
I'm getting the following error:
The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved
I have a web application which only my server will be accessing, the initial auth works fine, but after an hour, the aforementioned error message pops up. My script looks like this:
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("{MY_API_KEY}");
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setClientSecret('{MY_KEY}');
$client->setRedirectUri('{MY_REDIRECT_URI}');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
How can I set up a refresh token for this?
Edit 1: I've tried doing this with a Service account as well. I followed the documentation available on GitHub:
https://github.com/google/google-api-php-client/blob/master/examples/service-account.php
My script looks like this:
session_start();
include_once "templates/base.php";
require_once 'Google/Client.php';
require_once 'Google/Service/Gmail.php';
$client_id = '{MY_CLIENT_ID}.apps.googleusercontent.com';
$service_account_name = '{MY_EMAIL_ADDRESS}#developer.gserviceaccount.com ';
$key_file_location = 'Google/{MY_KEY_FILE}.p12';
echo pageHeader("Service Account Access");
if ($client_id == ''
|| !strlen($service_account_name)
|| !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
}
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$service = new Google_Service_Gmail($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/gmail.readonly'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
This returns the following message:
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }''
After tracking this code to it's source, which can be found in Google/Auth/OAuth2.php
The method in question, refreshTokenRequest:
private function refreshTokenRequest($params)
{
$http = new Google_Http_Request(
self::OAUTH2_TOKEN_URI,
'POST',
array(),
$params
);
$http->disableGzip();
$request = $this->client->getIo()->makeRequest($http);
$code = $request->getResponseHttpCode();
$body = $request->getResponseBody();
if (200 == $code) {
$token = json_decode($body, true);
if ($token == null) {
throw new Google_Auth_Exception("Could not json decode the access token");
}
if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
throw new Google_Auth_Exception("Invalid token format");
}
if (isset($token['id_token'])) {
$this->token['id_token'] = $token['id_token'];
}
$this->token['access_token'] = $token['access_token'];
$this->token['expires_in'] = $token['expires_in'];
$this->token['created'] = time();
} else {
throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
}
}
Which means that the $code variable is NULL.
I found this post on SO:
Error refreshing the OAuth2 token { “error” : “invalid_grant” }
And can see that there is still no prefered solution. This is driving me nuts. There is very little to no documentation available on this and if anybody has a solution, I'm sure I'm not the only one looking for it.
Each access_token expires after a few seconds and need to be refreshed by refresh_token, "Offline access" is what you are looking for. Here you can follow the documentation:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
To obtain a refresh_token you have to run this code only one time:
require_once 'Google/Client.php';
$client = new Google_Client();
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setClientSecret('{MY_KEY}');
$client->setRedirectUri('{MY_REDIRECT_URI}');
//next two line added to obtain refresh_token
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
if (isset($_GET['code'])) {
$credentials = $client->authenticate($_GET['code']);
/*TODO: Store $credentials somewhere secure */
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
$credentials includes an access token and a refresh token. You have to store this to obtain new access tokens at any time. So when you wanted to make a call to api:
require_once 'Google/Client.php';
require_once 'Google/Service/Gmail.php';
/*TODO: get stored $credentials */
$client = new Google_Client();
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setRedirectUri('{MY_REDIRECT_URI}');
$client->setClientSecret('{MY_KEY}');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
$client->setAccessToken($credentials);
$service = new Google_Service_Gmail($client);
I'm want to get google+ posts via PHP, but google requires my login via browser.
It's possible provide the account's authentication via PHP, allowing me to get the posts without login every time I want to get the posts?
The code is:
<?php
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_PlusService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google+ PHP Starter Application");
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('clientid');
$client->setClientSecret('clientsecret');
$client->setRedirectUri('http://localhost/OLA/google+/simple.php/b.html');
$client->setDeveloperKey('apikey');
$plus = new Google_PlusService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) { // login stuff <-------
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die("The session state did not match.");
}
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
//$me = $plus->people->get('me');
//print "Your Profile: <pre>" . print_r($me, true) . "</pre>";
$params = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $params);
//print "Your Activities: <pre>" . print_r($activities, true) . "</pre>";
$params = array(
'orderBy' => 'recent',
'maxResults' => '20'//20
);
$q = "tag";
$results = $plus->activities->search($q, $params);
//code ....
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
// This is the part that logs me in via browser <------
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
Yep, just call as you would and use the simple API access key - you can retrieve public information, but you will have to supply to long numeric ID for the user you're retrieving posts for rather than using the string 'me'. Take a look at the latest version of the library as well: https://github.com/google/google-api-php-client as well. You need to setup your client as you were doing, with an API key from a project which has the Google+ enabled on https://developers.google.com/console
$client = new Google_Client();
$client->setApplicationName("Post Fetcher");
$client->setDeveloperKey('PUT_YOUR_API_KEY_HERE_OR_IT_WONT_WORK');
$plus = new Google_Service_Plus($client);
$activities = $this->plus->activities
->listActivities("118051310819094153327", "public");