I cannot obtain stable script when I try upload docx file to Google Drive, and then download that file but as PDF.
Code:
//Google API
require_once('vendor/autoload.php');
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/2ab4ece19bd5.json');
$client = new Google_Client();
$client->setApplicationName('sp-gen');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$client->useApplicationDefaultCredentials();
$service = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => '281e2399740c88957143507721bd0f25.docx',
'mimeType' => 'application/vnd.google-apps.document'
));
$content = file_get_contents('281e2399740c88957143507721bd0f25.docx');
$file = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => 'application/vnd.google-apps.document',
'uploadType' => 'multipart',
'fields' => 'id')
);
$content = $service->files->export($file->id, 'application/pdf', array( 'alt' => 'media' ));
file_put_contents(str_replace('.docx', '.pdf', '281e2399740c88957143507721bd0f25.docx'), $content->getBody()->getContents());
This code works in.. 20-30% of uses. Sometimes, $service->files->export() return error code 500 but in many cases request return normal response (200) but with Content-Length 0.
Am I doing something wrong? Or should I do some kind of loop, that try download file until success?
OK. So I spend two days looking for solution and I came up with several conclusions:
You can assign permissions to created file, that connect your real google account to file, and than you can access that file via Google Drive. You can not transfer ownership to file from service account to google account, because Google PHP API at this moment do not have proper method. Or I do not see way to setup this. Class summary.
Key is to use Exponential backoff. In other words try unless success. ( ͡° ͜ʖ ͡°)
CODE:
//Google API
require_once('vendor/autoload.php');
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/2ab4ece19bd5.json');
$client = new Google_Client();
$client->setApplicationName('sp-gen');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$client->useApplicationDefaultCredentials();
$service = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => '281e2399740c88957143507721bd0f25.docx',
'mimeType' => 'application/vnd.google-apps.document'
));
$content = file_get_contents('281e2399740c88957143507721bd0f25.docx');
$file = $service->files->create($fileMetadata, array(
'data' => $content,
'uploadType' => 'multipart'
);
//Create new permission
$newPermission = new Google_Service_Drive_Permission();
//set email of account, that will have access to file.
$newPermission->setEmailAddress('<email here>');
//Must be user or group, if you pass email adress
// user | group | domain | anyone
$newPermission->setType('user');
//Could be owner but I can not set transferOwnership
// organizer | owner | reader | writer
$newPermission->setRole('writer');
$service->permissions->create($file->getId(), $newPermission);
$file_name = str_replace('.docx', '.pdf', '281e2399740c88957143507721bd0f25.docx');
$attempt = 1;
do{
//Wait 5000ms
usleep(500000*$attempt);
//Try to get pdf file.
$content = $service->files->export($file->getId(), 'application/pdf', array( 'alt' => 'media' ));
//Save just fetched data.
file_put_contents($file_name, $content->getBody()->getContents());
if(filesize($file_name)) break;
else $attempt++;
}while(true);