googleapis / google-api-php-client

A PHP client library for accessing Google APIs
http://googleapis.github.io/google-api-php-client/
Apache License 2.0
9.32k stars 3.52k forks source link

New errror while calling google_drive_service->files->copy #2401

Closed thesailorbreton closed 1 year ago

thesailorbreton commented 1 year ago

I suddenly encounter an issue on a script that has been running OK for Months when trying to copy a file in GoogleDrive:

$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid() . '.' . pathinfo($original_fil_path, PATHINFO_EXTENSION));
$file->setDescription('');
$file->setParents([$this->drive_client->getGoogledDriveCandidateDirectory($pla_tst_id)]);
$original_file_id = $this->drive_client->getFileID($original_fil_path, true);
$createdFile = $this->drive_client->google_drive_service->files->copy($original_file_id, $file);

And I get the following error Message :

{ "error": { "code": 400, "message": "Invalid value at 'payload' (Map), Cannot bind a list to map for field 'exportLinks'.", "errors": [ { "message": "Invalid value at 'payload' (Map), Cannot bind a list to map for field 'exportLinks'.", "reason": "invalid" } ], "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.BadRequest", "fieldViolations": [ { "field": "payload", "description": "Invalid value at 'payload' (Map), Cannot bind a list to map for field 'exportLinks'." } ] } ] } }
/htdocs/appdev/vendor/google/apiclient/src/Http/REST.php134
#0 /htdocs/appdev/vendor/google/apiclient/src/Http/REST.php(107): Google\Http\REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google\\Service\\...')
#1 [internal function]: Google\Http\REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google\\Service\\...')
#2 /htdocs/appdev/vendor/google/apiclient/src/Task/Runner.php(187): call_user_func_array(Array, Array)
#3 /htdocs/appdev/vendor/google/apiclient/src/Http/REST.php(66): Google\Task\Runner->run()
#4 /htdocs/appdev/vendor/google/apiclient/src/Client.php(921): Google\Http\REST::execute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google\\Service\\...', Array, NULL)
#5 /htdocs/appdev/vendor/google/apiclient/src/Service/Resource.php(238): Google\Client->execute(Object(GuzzleHttp\Psr7\Request), 'Google\\Service\\...')
#6 /htdocs/appdev/vendor/google/apiclient-services/src/Drive/Resource/Files.php(72): Google\Service\Resource->call('copy', Array, 'Google\\Service\\...')
#7 /htdocs/appdev/phpclass/question/script/googleworkspace.script.question.class.php(115): Google\Service\Drive\Resource\Files->copy('1pMB7Jy38tIKveW...', Object(Google\Service\Drive\DriveFile))

Any help would be greatly appreciated.

CostiNec commented 1 year ago

Hi, I've faced this problem. Try to unset the exportLinks from Google_Service_Drive_DriveFile class. For example this is how your code should look like:

$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid() . '.' . pathinfo($original_fil_path, PATHINFO_EXTENSION));
$file->setDescription('');
$file->setParents([$this->drive_client->getGoogledDriveCandidateDirectory($pla_tst_id)]);
unset($file->exportLinks);
$original_file_id = $this->drive_client->getFileID($original_fil_path, true);
$createdFile = $this->drive_client->google_drive_service->files->copy($original_file_id, $file);

This is not the real solution, but until google solve this problem, this could be a good hotfix.

Hope this will fix your problem.

thesailorbreton commented 1 year ago

It worked.

Thanks a lot.

I mean it.

Thanks a lot !

mihail-minkov commented 1 year ago

Hi, I've faced this problem. Try to unset the exportLinks from Google_Service_Drive_DriveFile class. For example this is how your code should look like:

$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid() . '.' . pathinfo($original_fil_path, PATHINFO_EXTENSION));
$file->setDescription('');
$file->setParents([$this->drive_client->getGoogledDriveCandidateDirectory($pla_tst_id)]);
unset($file->exportLinks);
$original_file_id = $this->drive_client->getFileID($original_fil_path, true);
$createdFile = $this->drive_client->google_drive_service->files->copy($original_file_id, $file);

This is not the real solution, but until google solve this problem, this could be a good hotfix.

Hope this will fix your problem.

I ran into this issue today after updating google-api , this solved my issue too.

Olliug91 commented 1 year ago

Hi. I try this solution @mihail-minkov , but it still not working. In my case I get the error when I try to delete a file in drive(last line). This is my code:

$contents = collect(Storage::disk('google')->listContents($dir,$recursive)); $file = $contents ->where('type',"=",'file') ->where('filename','=',pathinfo($filename,PATHINFO_FILENAME)) ->where('extension','=',pathinfo($filename, PATHINFO_EXTENSION)) ->first(); $urlFile = Storage::disk('google')->url($file['path']); ... Storage::disk('google')->delete($file['path']);

Any help would be greatly appreciated.

modernben commented 1 year ago

@Olliug91 You need to edit the underlying package that actually interacts with the Google side of things. For me, this was in the GoogleDriveAdapter.php class. I needed to add it to anything that modifies a file (copy, rename, move, create, and delete).

saranshdhingra commented 1 year ago

Hi @thesailorbreton Thanks for filing this issue. Seems like a lot of people are having this problem.

However, when I tried the same with the following code, I didn't get any error.

$file = new Google\Service\Drive\DriveFile();
$file->setName("NAME_OF_DESTINATION_FILE"); // with extension
$file->setDescription('');
$file->setParents(["ID_OF_PARENT_FOLDER"]);
$originalFileId = "ID_OF_SRC_FILE";
$createdFile = $service->files->copy($originalFileId, $file);

I obviously removed the variables to try and use the values directly. Could someone help me and probably add a gist that helps me reproduce the issue? A Dockerfile might go a long way :)

R2116 commented 1 year ago

@saranshdhingra Thanks for looking into this. I have the same issue of reproducing the error: I updated the dependencies of a project of a client to make it PHP 8-compatible, tested it, and everything worked. A few days after going live the issue appeared (both on staging and live), like for the thread-starter and the hotfix does the trick. I did not program the project, don't know much about the library used, only updated dependencies now. Any idea how I could help you with this?

The code causing the error:

$emptyFile = new Google_Service_Drive_DriveFile();
$emptyFile->setMimeType('application/vnd.google-apps.spreadsheet');

/**
 * Temporary hotfix to error with export link structure
 * @since 1.1.1
 * @see https://github.com/googleapis/google-api-php-client/issues/2401#issuecomment-1460229580
 */
$emptyFile->setExportLinks( null );

$result = $service->files->update($fileId, $emptyFile, array(
    'data' => file_get_contents($filePath),
    'mimeType' => 'application/vnd.google-apps.spreadsheet',
    'uploadType' => 'multipart'
));
thesailorbreton commented 1 year ago

@saranshdhingra , I am in the same situation, without changing anything else, if I simply remove the unset($file->exportLinks); the code now works again.

So basically, it has stopped working without any change on my side and it's now working again without any change. This must be coming from a change the Google API behavior.

By safety measusre I will keep the unset($file->exportLinks) for now.

Regards,

Marc

saranshdhingra commented 1 year ago

Hi @R2116 Thanks for the help.

I even tried the code snippet you gave, with and without the $emptyFile->setExportLinks( null ); and currently I didn't receive any error. I hope your'e not seeing the error when you remove the line, right now?

Just for future purpose, you can see the version of the library use with: composer show google/apiclient.

@thesailorbreton That does seem like a valid explanation but it should certainly not be the case. I'll try to get some more details internally.

I'll be closing this for now, if this error does occur again, please reopen this one, or create a new one linking this one.

Thanks.

bshaffer commented 1 year ago

We dealt with an issue that has since been fixed, when trying to add PHP 8.1 compatibility. See https://github.com/googleapis/google-api-php-client-services/pull/2437 for more info.

Now you should be able to just update to the latest versions of google/apiclient and google/apiclient-services, and this will be fixed.