1

I just set up Google Drive API Change Notifications, specifying the folderId of a certain shared folder that I have on My Drives. It sends notifications if I change the folder name, but doesn't send notifications if I add files.

I set up the channel successfully, as upon issuing these PHP commands

    $client = new Google_Client();
    $client->setApplicationName('Some Name');
    $client->setAuthConfig( __DIR__  . '/service_account.json');
    $client->setScopes(Google_Service_Drive::DRIVE);
    $client->fetchAccessTokenWithAssertion();
    $token = $client->getAccessToken();
    $service = new Google\Service\Drive($client);
    $httpclient = new \GuzzleHttp\Client();
    $folderid = $someid;
    $body = [
        'kind' => "api#channel",
        'id' => uniqid(),
        'type' => 'web_hook',
        'resourceId' => $folderid,
        'resourceUri' => 'https://www.googleapis.com/drive/v3/files/'.$folderid,
        'address' => 'myendpoint'
    ];

    $apiendpoint = 'https://www.googleapis.com/drive/v3/files/' . $folderid . '/watch';
    $result = $httpclient->post($apiendpoint, [
        'headers' => ['Content-Type' => 'application/json', 'Authorization' => "Bearer {$token['access_token']}"],
        'body' => json_encode($body),
        "http_errors" => false]);

I see a successful return, and my channel immediately sends a sync message to my endpoint, where I have this

function myendpoint (WP_REST_Request $request) {
    $headers= getallheaders();
    write_log('in google drive webhook with headers '.print_r($headers, true));
    $body = $request->get_body();
    write_log('in google drive webhook with body '.print_r($body, true));
    global $wpdb;
    return http_response_code(200);
}

Via my logging, I see

[07-Nov-2021 12:52:35 UTC] in google drive webhook with headers Array
(
    [Host] => courses-test.com
    [User-Agent] => APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)
    [Content-Length] => 0
    [Accept] => */*
    [Accept-Encoding] => gzip, deflate, br
    [X-Forwarded-For] => 66.102.8.121
    [X-Forwarded-Proto] => https
    [X-Goog-Channel-Expiration] => Sun, 07 Nov 2021 13:51:26 GMT
    [X-Goog-Channel-Id] => 6187cbc82a08e
    [X-Goog-Message-Number] => 1
    [X-Goog-Resource-Id] => resid
    [X-Goog-Resource-State] => sync
    [X-Goog-Resource-Uri] => https://www.googleapis.com/drive/v3/files/folderid?acknowledgeAbuse=false&supportsAllDrives=false&supportsTeamDrives=false&alt=json
    [X-Original-Host] => mydomain
)

I read here

https://developers.google.com/drive/api/v3/push

where it says

"To indicate success, you can return any of the following status codes: 200, 201, 202, 204, or 102."

and hence I am returning return http_response_code(200);

and also read here

https://developers.google.com/drive/api/v3/reference/files/watch

and I don't see anything obvious going on here.

Here

https://developers.google.com/search/docs/advanced/crawling/apis-user-agent?visit_id=637718909398077288-2640249237&rd=1

there is this remark

"Avoid unnecessary retry requests by ensuring that your application is well-designed and responds promptly to notification messages (within seconds)."

Now, when I first set up the channel, my endpoint returns right away, so that would seem to negate the above point.

Also, after I get channel set up, I also run these lines

        $optParams = array(
            'pageSize' => 10,
            'fields' => 'nextPageToken, files(id, name)'
        );
        $results = $service->files->listFiles($optParams);

and indeed see a listing of files.

So I truly at a loss. When I go into the folder, whose folderId I specified to set up the watch channel, and add a file, or edit a file, I don't receive any notifications. The folder in question is shared, but as I understand, sharing only becomes an issue when dealing with shared drives, which is not my case.

And I read here,

https://developers.google.com/drive/api/v3/push#understanding-drive-api-notification-events

that watching for files being added should indeed work on a file watch, when the file is a folder, since add is one of the events for a resource, and it applies to Files.


**Update: Ok, I seem to have things working, but not based on an add event. The only thing I changed, is that instead of using Guzzle to make the POST, as I show above, I use this

    $channel->setId(uniqid());
    $channel->setAddress($body['address']);
    $channel->setType('web_hook');
    $test = $service->files->watch($folderid, $channel);

Maybe adding some of those extra params in the $body like kind, resourceId, was messing things up when I was using POST via Guzzle. Or now that I know resourceId is not same as folderid, maybe that threw a flag on google's end so that a limited number of notifications were being sent. In any case, just using id', address and type seems to be the way to go, which I think is in the Google Drive Push docs. Just that in those docs, also mention of adding those other params in the request, like 'resourceId'. I suspect if I redo using Guzzle, but specify correct resourceId, or just leave it out and use id', address and type, that it would work.

So now, I get this sort of header in my endpoint when I add a file:

(
    [Host] => courses-test.com
    [User-Agent] => APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)
    [Content-Length] => 0
    [Accept] => */*
    [Accept-Encoding] => gzip, deflate, br
    [X-Forwarded-For] => someip
    [X-Forwarded-Proto] => https
    [X-Goog-Changed] => children
    [X-Goog-Channel-Expiration] => Mon, 08 Nov 2021 09:46:10 GMT
    [X-Goog-Channel-Id] => chanid
    [X-Goog-Message-Number] => num
    [X-Goog-Resource-Id] => someid
    [X-Goog-Resource-State] => update
    [X-Goog-Resource-Uri] => https://www.googleapis.com/drive/v3/files/folderid?acknowledgeAbuse=false&supportsAllDrives=false&supportsTeamDrives=false&alt=json
    [X-Original-Host] => mydomain
)

So I can detect [X-Goog-Changed] as being children and just keep track of my current uploaded files and see what the new file is. Or maybe using the fields query string somehow I can directly get the new file id?

Still seems odd that getting info about a new file is such a pain. Maybe it is easier in Google Cloud API and Google wants more people signing up for Cloud. In fact that add event only seems to apply to Cloud buckets.

Brian
  • 561
  • 5
  • 16
  • To `doesn't send notifications if I add files`: Is it you (the watch creator) or another user who is adding files? – ziganotschka Nov 08 '21 at 08:50
  • I am adding the file from my MAC, using the Google Drive App, while signed in to Google Drive via my account where the shared folder is. That folder is also shared with the service account email whose credentials are used for the API interaction. In any case, seems to be working now (I edited above). – Brian Nov 08 '21 at 12:05
  • Well, maybe your answer is correct. In my case, the `add` notificaton is not working. Also, I just noticed that I am only getting notifications when a folder is added. If I add files, there are no notifications. Maybe because I tell Google to watch a folder, it returns notifications for changes only pertaining to child folders. Weird... – Brian Nov 09 '21 at 06:55
  • This makes sense. I just thought that the issue had been fixed - given that it seemed to work for you. – ziganotschka Nov 09 '21 at 08:04

1 Answers1

0

In short: When watching a folder with files().watch() it is currently not possible to receive notifications about new files added to this folder

There are several workarounds that you can find along with explanations in answers to similar questions:

Also: There is a relevant feature request on Google's Issue Tracker.

It has been closed due to inactivity, but it is worth "starring" and commenting on it to increase visibility.

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • Actually, works now, using files watch channel. My only change was to use the PHP Google library calls to set the channel, as opposed to using Guzzle and making an Http POST. Even though my Http POST was successfully setting the channel, maybe there was just something about my POST that wasn't enabling some setting on google's end. In my case, it is a folder that I have control over, and I know the only actions I take in that folder are adding and removing files. So while I don't get specially a 'file added' event, I do get an update event, telling me children changed. More above in my post – Brian Nov 08 '21 at 11:49