Google Api for PHP (Drive API) 导出为 .pdf 上传的 .docx 文件

Google Api for PHP (Drive API) Export as .pdf uploaded .docx file

当我尝试将 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->files->export() return 错误代码 500 但在许多情况下请求 return 正常响应 (200) 但具有 Content-Length 0.

我是不是做错了什么?或者我应该做某种循环,尝试下载文件直到成功?

好的。所以我花了两天时间寻找解决方案,得出了几个结论:

  1. 使用服务器到服务器身份验证,您必须创建 服务帐户,并使用 "separate" google 驱动器帐户。这意味着如果您通过脚本创建文件,文件将在服务帐户上创建,并且您只能通过 API.
  2. 访问该文件
  3. 您可以为创建的文件分配权限,将您的真实 google 帐户连接到文件,然后您可以通过 Google 驱动器访问该文件。您不能将文件的所有权从服务帐户转移到 google 帐户,因为 Google PHP API 目前没有正确的方法。 或者我不知道如何设置它。 Class summary.

  4. 关键是要用Exponential backoff。换句话说尝试除非成功。 ( ͡° ͜ʖ ͡°)

代码:

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