Cannot upload file to Google Drive using API for service account - php

To upload files to Google Drive using service account, I have written the following code which is from this link: https://developers.google.com/drive/web/service-accounts
My code:
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DriveService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
$DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive';
$SERVICE_ACCOUNT_EMAIL = '<some-id>#developer.gserviceaccount.com';
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/<public_key_fingerprint>-privatekey.p12';
/**
* Build and returns a Drive service object authorized with the service accounts.
*
* #return Google_DriveService service object.
*/
function buildService() {
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
SERVICE_ACCOUNT_EMAIL,
array(DRIVE_SCOPE),
$key);
$client = new Google_Client();
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
return new Google_DriveService($client);
}
function uploadFile($service, $mime, $src) {
//Insert a file
$file = new Google_DriveFile();
$file->setMimeType($mime);
$data = file_get_contents($src);
try {
//ERROR HERE: cannot insert (upload) file
$createdFile = $service->files->insert($file,
array(
'data' => $data,
'mimeType' => $mime,
'convert' => true,
)
);
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
$service = buildService();
When I call the buildService() method, it gives me an error:
Catchable fatal error: Object of class Google_AssertionCredentials could not be converted to string in /opt/lampp/htdocs/ajaxGoogleDrive/google-api-php-client/src/auth/Google_OAuth2.php on line 197
Where am I going wrong?

Related

How can I view the path from the 'google drive api' file list

I have followed https://developers.google.com/drive/api/v2/reference/files/list, successful! I got it all. But not my 'drive'. I received a warning 'You need to be granted access here. So what should I do to fix the above error?
I created a new project, Service account keys and OAuth 2.0 client IDs. but it's bad it doesn't properly link to my 'google drive' account
This is my whole code
<?php
session_start ();
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
require_once 'vendor/autoload.php';
$DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive';
$SERVICE_ACCOUNT_EMAIL = 'xxx#phim-240702.iam.gserviceaccount.com';
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = 'phim-240702-a98343eb742a.p12';
function buildService(){
global $DRIVE_SCOPE, $SERVICE_ACCOUNT_EMAIL, $SERVICE_ACCOUNT_PKCS12_FILE_PATH;
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
$SERVICE_ACCOUNT_EMAIL,
array($DRIVE_SCOPE),
$key);
$client = new Google_Client();
$client->setApplicationName("googletest5");
$client->setDeveloperKey("b2016fa55e916faf35337ccb1db830ecdb590cc3");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
return new Google_DriveService($client);
}
/**
* Insert new file.
*
* #param Google_Service_Drive $service Drive API service instance.
* #param string $title Title of the file to insert, including the extension.
* #param string $description Description of the file to insert.
* #param string $parentId Parent folder's ID.
* #param string $mimeType MIME type of the file to insert.
* #param string $filename Filename of the file to insert.
* #return Google_Service_Drive_DriveFile The file that was inserted. NULL is
* returned if an API error occurred.
*/
function insertFile($service, $title, $description, $parentId, $mimeType, $filename) {
$file = new Google_DriveFile();
$file->setTitle($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new Google_Service_Drive_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => '$mimeType',
));
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
/**
* Retrieve a list of File resources.
*
* #param Google_Service_Drive $service Drive API service instance.
* #return Array List of Google_Service_Drive_DriveFile resources.
*/
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array(
'maxResults' => '100'
);
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
try {
$root_id = null;
$service = buildService();
print_r(retrieveAllFiles($service));
}catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
?>
What you need to remember is that a Service account is not you. A service account is a dummy user. It has its own google drive account. when you upload the files to the service accounts drive account they are only accessible by that account as it is the owner of it.
Share a drive
If you want it to be able to access files on your personal drive account you will need to grant it access to them by sharing them with the service accounts email address. This is how service accounts are pre approved.
getting path
As for getting the path of a file there is no easy way to do that you will need to step your way though it by getting the file, then getting its parent, followed by getting any more parents until you hit the top and build it up that way.

Google Drive Api intergration with php

I want to show my google drive into website. Which means if anybody use my website can see google drive files and folder without login. Here is some code which i am trying to implement.
include_once 'google-api-php-client/src/Google/autoload.php';
$scopes = array( 'https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.appdata',
'https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive.metadata','https://www.googleapis.com/auth/drive.metadata.readonly','https://www.googleapis.com/auth/drive.photos.readonly','https://www.googleapis.com/auth/drive.readonly');
/**
* Create AssertionCredentails object for use with Google_Client
*/
$creds = new Google_Auth_AssertionCredentials(
$serviceAccountName,
$scopes,
file_get_contents($keyFile)
);
$creds->sub = $delegatedAdmin;
/**
* Create Google_Client for making API calls with
*/
$client = new Google_Client();
$client->setApplicationName($appName);
$client->setClientId($clientId);
$client->setAssertionCredentials($creds);
/**
* Get an instance of the Directory object for making Directory API related calls
*/
$service = new Google_Service_Drive($client);
$optParams = array(
'pageSize' => 10,
'fields' => "nextPageToken, files(id, name)"
);
$results = $service->files->listFiles($optParams);
print_r($results); exit;
/**
Can anybody tel me how to achieve this. I am getting this error
Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Error refreshing the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }
You need to add
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
after
$client->setAssertionCredentials($creds);

PHP: Uploading file to google drive with service account

I am trying to upload a pdf to google drive as a service account in php.
I get a browser error: ERR_CONNECTION_RESET when trying to upload.
I got the code from here:
https://developers.google.com/drive/web/service-accounts#next_steps
and
https://developers.google.com/drive/v2/reference/files/insert
<?php
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DriveService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
$DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive';
$SERVICE_ACCOUNT_EMAIL = 'xxx#developer.gserviceaccount.com';
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = 'API Project-xxx.p12';
/**
* Build and returns a Drive service object authorized with the service accounts.
*
* #return Google_DriveService service object.
*/
function buildService() {
global $DRIVE_SCOPE, $SERVICE_ACCOUNT_EMAIL, $SERVICE_ACCOUNT_PKCS12_FILE_PATH;
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
$SERVICE_ACCOUNT_EMAIL,
array($DRIVE_SCOPE),
$key);
$client = new Google_Client();
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
return new Google_DriveService($client);
}
/**
* Insert new file.
*
* #param Google_DriveService $service Drive API service instance.
* #param string $title Title of the file to insert, including the extension.
* #param string $description Description of the file to insert.
* #param string $parentId Parent folder's ID.
* #param string $mimeType MIME type of the file to insert.
* #param string $filename Filename of the file to insert.
* #return Google_DriveFile The file that was inserted. NULL is returned if an API error occurred.
*/
function insertFile($service, $title, $description, $parentId, $mimeType, $filename) {
$file = new Google_DriveFile();
$file->setTitle($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new Google_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
));
// Uncomment the following line to print the File ID
// print 'File ID: %s' % $createdFile->getId();
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
$service=buildService();
$title='test';
$description='qqq';
$parentId='';
$mimeType='application/pdf';
$filename='doc.pdf';
insertFile($service, $title, $description, $parentId, $mimeType, $filename)
?>

Google Api Client PHP - Create Fusion Table

With the newest version of the Google Api Client for PHP it is hard to come by examples that work. The Documentation is also very slim.. Ive tried a LOT and can't figure out how to login/authenticate so I can create/insert into Fusion Tables.
Ive tried with oAuth and with a Service Token (with a p12 file).
I am able to retrieve data from a Fusion Table and log it to FireBug (with FirePHP). But this only needs the Developer ID and no authentication.
If somebody has a working example Id be very grateful!
My trials:
class GoogleClass {
protected $firephp;
public function init() {
session_start();
require_once 'Google/Client.php';
require_once 'Google/Auth/AssertionCredentials.php';
#require_once 'Google/Auth/OAuth2.php';
require_once 'Google/Service/Fusiontables.php';
#require_once 'Google/Service/Urlshortener.php';
#require_once 'Google/Service/Oauth2.php';
/*
Service Auth
$client_id = 'client_id';
$service_account_name = 'service_account_name';
$key_file_location = 'key_file_location';
$client = new Google_Client();
$client->setApplicationName('FusionTableConnect');
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('http://www.googleapis.com/auth/fusiontables'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
try {
$client->getAuth()->refreshTokenWithAssertion($cred);
} catch (Exception $e) {
$this->firephp->error($e);
}
}
$_SESSION['service_token'] = $client->getAccessToken();
*/
/*
Execute Query to get Table results
*/
$client = new Google_Client();
$client->setDeveloperKey('developerKeyServer'); // Server Application API key - Query
$tableId = 'tableId';
$ft = new Google_Service_Fusiontables($client);
try {
$result = $ft->query->sql("SELECT gm_code FROM $tableId");
$this->firephp->log($result, 'Array');
} catch (Exception $e) {
$this->firephp->error($e);
}
/* ------------------------------------------------------------------------------ */
/*
Google Client setup
$client = new Google_Client();
#$client->setApplicationName('TestApp');
$client->setClientId('clientId'); // Web application Client ID
$client->setClientSecret('clientSecret'); // Web application Secret key
#$client->addScope('https://www.googleapis.com/auth/fusiontables'); // Fusion Tables scope
$client->setRedirectUri('redirectUri');
#$client->setDeveloperKey('developerKeyServer'); // Server Application API key - Query
#$client->setDeveloperKey('developerKeyBrowser'); // Browser Application API key
*/
/*
oAuth2 Identification
$service = new Google_Service_Urlshortener($client);
#$client->addScope(Google_Service_Urlshortener::URLSHORTENER);
$client->setScopes("https://www.googleapis.com/auth/plus.login");
$authUrl = $client->createAuthUrl();
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
}
*/
/*
Fusion Tables
$service = new Google_Service_Fusiontables($client);
try {
$result = $service->query->sql("SELECT gm_code FROM tableId");
$this->firephp->log($result, 'Array');
} catch (Exception $e) {
$this->firephp->error($e);
}
$column = new Google_Service_Fusiontables_Column();
$column->setName('foo');
$column->setType('STRING');
$table = new Google_Service_Fusiontables_Table();
$table->setName('bar');
$table->setColumns(array($column));
try {
$service->table->insert($table);
} catch(Exception $e) {
$this->firephp->error($e);
}*/
}
public function firePHPInit($auto) {
require_once('FirePHPCore/FirePHP.class.php');
ob_start();
$this->firephp = FirePHP::getInstance(true);
if ($auto) {
$this->firephp->registerErrorHandler(
$throwErrorExceptions=false);
$this->firephp->registerExceptionHandler();
$this->firephp->registerAssertionHandler(
$convertAssertionErrorsToExceptions=true,
$throwAssertionExceptions=false);
/*try {
throw new Exception('Test Exception');
} catch(Exception $e) {
$this->firephp->error($e); // or FB::
}*/
}
}
}
I think this may help you. this is official document for php-client from zend
http://framework.zend.com/manual/1.11/en/zend.gdata.photos.html
But I suggest to use oAuth 2.0

Display Google Admin SDK JSON Response in PHP

Thanks to Emily, I found the php client library already. I need to retrieve a users data. There is a function in the API that can do so :
Google_DirectoryService.php
/**
* retrieve user (users.get)
*
* #param string $userKey Email or immutable Id of the user
* #param array $optParams Optional parameters.
* #return Google_User
*/
public function get($userKey, $optParams = array()) {
$params = array('userKey' => $userKey);
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_User($data);
} else {
return $data;
}
}
index.php
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DirectoryService.php';
$client = new Google_Client();
$client->setApplicationName("IAA SIS");
$client->setClientId('xxx.apps.googleusercontent.com');
$client->setClientSecret('xxx');
$client->setRedirectUri('http://mypage.com/oauth2callback');
$client->setDeveloperKey('xxx');
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/admin.directory.user.readonly'));
$service = new Google_DirectoryService($client);
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2
$results = $service->users->get('$email', 'public', $optParams); //Pass email to function parameter ? I'm not sure.
?>
I think the way I pass the parameter is wrong which i got error after adding the last line. How do I pass users login email to the function correctly ?
The error i got is :
[08-Jan-2014 03:17:33 America/Chicago] PHP Fatal error: Uncaught exception 'Google_ServiceException' with message 'Error calling GET https://www.googleapis.com/admin/directory/v1/users/me?key=: (403) Insufficient Permission' in /home2/iaapro/public_html/php/google-api-php-client/src/io/Google_REST.php:66
Stack trace:
#0 /home2/iaapro/public_html/php/google-api-php-client/src/io/Google_REST.php(36): Google_REST::decodeHttpResponse(Object(Google_HttpRequest))
#1 /home2/iaapro/public_html/php/google-api-php-client/src/service/Google_ServiceResource.php(186): Google_REST::execute(Object(Google_HttpRequest))
#2 /home2/iaapro/public_html/php/google-api-php-client/src/contrib/Google_DirectoryService.php(653): Google_ServiceResource->__call('get', Array)
#3 /home2/iaapro/public_html/php/google-plus-access.php(44): Google_UsersServiceResource->get('me')
#4 /home2/iaapro/public_html/php/index.php(2): include_once('/home2/iaapro/p...')
#5 {main}
thrown in /home2/iaapro/public_html/php/google-api-php-client/src/io/Google_REST.php on line 66
In addition, I have checked "Enable API Access" on admin.google.com and enable Admin SDK on Google APIs Console.
Can anyone gives me some help please ?
Finally, I figured out how to call the array using Google directory service API. Please refer to the code below:
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
require_once 'google-api-php-client/src/contrib/Google_DirectoryService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("ApplicationName");
//*********** Replace with Your API Credentials **************
$client->setClientId('Your_Client_ID');
$client->setClientSecret('Your_Client_Sercret');
$client->setRedirectUri('http://example.com/oauth2callback');
$client->setDeveloperKey('Your_API_Key');
//************************************************************
$client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/admin.directory.user.readonly'));
$plus = new Google_PlusService($client);
$oauth2 = new Google_Oauth2Service($client); // Call the OAuth2 class for get email address
$adminService = new Google_DirectoryService($client); // Call directory API
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
}
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['access_token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
}
if ($client->getAccessToken()) {
$user = $oauth2->userinfo->get();
$me = $plus->people->get('me');
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2
$optParams = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $optParams);
$users = $adminService->users->get($email);
$_SESSION['access_token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
}
?>
Have you checked out the Google API PHP client library? (https://code.google.com/p/google-api-php-client/)
Also, they have a github page: https://github.com/google/google-api-php-client
Once you downloaded the library from the site, you can see that the library has the Google_DirectoryService

Categories