Google Api для PHP (Drive API) Экспорт в формате.pdf uploaded.docx файл


Я не могу получить стабильный скрипт, когда пытаюсь загрузить файл docx на Google Диск, а затем загрузить этот файл, но в формате PDF.

Код:

//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());

Этот код работает в.. 20-30% случаев использования. Иногда $service->файлы->экспорт() возвращает код ошибки 500, но во многих случаях запрос возвращает обычный ответ (200), но с длиной содержимого 0.

Я делаю что-то не так? Или я должен сделать какой-то цикл, который пытается загрузить файл до успеха?

Author: Jędrzej Skrzypczak, 2017-07-28

1 answers

ХОРОШО. Поэтому я потратил два дня на поиски решения и пришел к нескольким выводам:

  1. Используя межсерверную аутентификацию, вы должны создать учетную запись службы с "отдельной" учетной записью Google диска. Это означает, что если вы создаете файл с помощью скрипта, файл создается в учетной записи службы, и вы можете получить доступ к этому файлу только через API.
  2. Вы можете назначить разрешения для созданного файла, которые подключают вашу реальную учетную запись Google к файлу, и чем вы можете получить доступ этот файл через Google Диск. Вы не можете передать право собственности на файл из учетной записи службы в учетную запись Google, потому что Google PHP API на данный момент не имеет надлежащего метода. Или я не вижу способа настроить это. Краткое описание класса.

  3. Ключ состоит в том, чтобы использовать Экспоненциальный откат. Другими словами, старайтесь, если не добьетесь успеха. (° ʖ °)

КОД:

//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);
 1
Author: Jędrzej Skrzypczak, 2017-07-31 12:05:35