I have a script that synchronizes changes with Google Drive via the service->changes->listChanges mechanism. This is the general approach (php code here)
$idChangeHistory = [] ;
do {
$response = $service->changes->listChanges($startPageToken, [ 'spaces' => 'drive' ] ) ;
if ( (! is_null($response->newStartPageToken))) {
$savedStartPageToken = $response->newStartPageToken ;
$historyRow['nextStartPageToken'] = $savedStartPageToken ;
$updateHistory = true ;
}
// I collect the change IDs because there may be multiple changes per file. We don't care how many hanges ocurred - we only want to know the object changed.
foreach ($response->changes as $change) {
$googleId = $change->fileId ;
if (array_key_exists($googleId, $idChangeHistory))
$idChangeHistory[$googleId]['count']++ ;
else
$idChangeHistory[$googleId] = [ 'count' => 1 ] ;
$idChangeHistory[$googleId]['removed'] = $change->removed ; // Is this permanently removed from the drive?
}
$startPageToken = $response->nextPageToken ;
} while ($startPageToken) ;
foreach ($idChangeHistory as $googleId => $elements) {
// Process each changed object
$fileObj = $service->files->get($googleId, [ 'fields' => 'id,name,mimeType,fileExtension,size,parents,createdTime,modifiedTime,trashed,md5Checksum' ] ) ;
... process each object here
}
All works well, except that periodically a phantom file will appear that is not part of Google Drive. This is either a file recently opened that has been shared with me, or some file that I've shared that is outside of the Google Drive realm (Google Sheets, for example). Ideally, the script should be able to detect and ignore such entities. (In truth, I think that's the job of the 'space' attribute, too.)
I found an article (https://developers.google.com/workspace/drive/api/guides/shared-drives-diffs) that mentions attributes "not populated" (definition unknown) in Shared files versus Drive files. Unfortunately, I have found that nearly all of these attributes (when they exist) are set to null, and that some (for example, driveId) exist as null values in both Drive files and Shared files. Presently, the script uses the approach that if a parent folder value is null, then it must be a shared file. But I am not convinced that this is a reliable test, given that none of the other values listed in the article seem to be reliable.
Is there a definitive and reliable method that can be used to establish whether a file truly is a drive file or a shared file? Beyond that, is there a way to determine if a "shared" file is shared with me or shared by me?
Of course, the other disturbing thing about this is that specifiecation of spaces=>'drive' theoretically should have avoided this question altogether. Is there something wrong with the assumption that spaces=>'drive' should ONLY include changes to drive objects?
UPDATE
The suggestion made by 4thAnd1 in the accepted answer, was to modify the list of fields as follows. This worked great for me, allowing me to test fields like ownedByMe, owners[0]->emailAddress, et cetera.
$fileObj = $service->files->get($googleId, [ 'fields' => 'id,name,mimeType,fileExtension,size,parents,createdTime,modifiedTime,trashed,ownedByMe,driveId,owners,permissions,md5Checksum' ] ) ;
I explored the Google Drive API and tried to find methods that could give you the desired solution for your concern but after spending some time, I found nothing that could give the desired result in a straing-forward manner.
One thing I found however is an alternative approach that you can try on your existing work.
You can utilize Google Drive API's files.get method and add the owners
field and then check owner's email if that matches yours then you can determine if it's a user-owned file or a shared one.
Sample Code
GET https://www.googleapis.com/drive/v3/files/<file-id-here>?fields=owners&key=[YOUR_API_KEY] HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN] Accept: application/json
Sample Output
{
"owners":
[
{
"kind": "drive\#user",
"displayName": "[Owner's display name]",
"photoLink": "[photo-link here]",
"me": false,
"permissionId": "[permission-id-here]",
"emailAddress": "owneremail@mail.com"
}]
}
Note:
I utilized the Google API Explorer for this and the sample code and output are from there as well.
References: