Search code examples
node.jsgoogle-drive-api

How can I get the resource with a resource ID in Google Drive API Node.js SDK?


Original Question

I registered a watch channel for a Google Drive folder and received a notification that it was updated. (Using Google Drive API Node.js SDK v3)

{
  host: 'my-development-host.example.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': 'xxx.xxx.xxx.xxx',
  'x-forwarded-proto': 'https',
  'x-goog-changed': 'children',
  'x-goog-channel-expiration': 'Tue, 11 May 2021 10:21:53 GMT',
  'x-goog-channel-id': '8f76c160-b229-11eb-a810-93ba607a525b',
  'x-goog-message-number': '1356107',
  'x-goog-resource-id': 'li76v1_bIpI23HBJ13dAqo66pYQ',
  'x-goog-resource-state': 'update',
  'x-goog-resource-uri': 'https://www.googleapis.com/drive/v3/files/1_ihmP2rHCBMXe7aQkW32bjZMccXzsPjE?acknowledgeAbuse=false&supportsAllDrives=false&supportsTeamDrives=false&alt=json'
}

The file ID of the folder which I was watching, is 1_ihmP2rHCBMXe7aQkW32bjZMccXzsPjE and I know that it is included in x-goog-resource-uri, so that I can access the folder with that file ID.

In the official document, resource ID is version-independent.

Note: The resourceId property is a stable, version-independent identifier for the resource. The resourceUri property is the canonical URI of the watched resource in the context of the current API version, so it’s version-specific.

I would like to get the version-independent resource data. However, I don't know how to get the resource data with x-goog-resource-id, resource ID.

Could anyone advise me, please? If possible not on Node.js SDK but on API style, it would be ok.

Edit

According to the sample in the official document, resourceId is the same as the one in resource URI and the comment tells that it is ID of the watched resource. I think the watched resource means a file resource.

The below sample is copied from it:

{
  "kind": "api#channel",
  "id": "01234567-89ab-cdef-0123456789ab", // ID you specified for this channel.
  "resourceId": "o3hgv1538sdjfh", // ID of the watched resource.
  "resourceUri": "https://www.googleapis.com/drive/v3/files/o3hgv1538sdjfh", // Version-specific ID of the watched resource.
  "token": "target=myApp-myFilesChannelDest", // Present only if one was provided.
  "expiration": 1426325213000, // Actual expiration time as Unix timestamp (in ms), if applicable.
}

In my case, I received the similar response, but URI style and resource ID usage(?) may different from the sample.

{
  kind: 'api#channel',
  id: '8f76c160-b229-11eb-a810-93ba607a525b',
  resourceId: 'li76v1_bIpI23HBJ13dAqo66pYQ',
  resourceUri: 'https://www.googleapis.com/drive/v3/files/1_ihmP2rHCBMXe7aQkW32bjZMccXzsPjE?acknowledgeAbuse=false&supportsAllDrives=false&supportsTeamDrives=false&alt=json',
  expiration: '1620728513000'
}

Solution

  • The x-goog-resource-id is not the same as the file/folder ID that you are watching.

    From the documentation:

    An opaque value that identifies the watched resource. This ID is stable across API versions.

    Understanding the notification message format

    This means that Google will create a new ID for the watched resource that is unique to the file/folder, but is not the same as the file/folder ID. The opaque part means that this is just another ID for you to identify the watch channel. Google probably uses it internally, but being opaque means that it is not something that we can see the workings of.

    To identify the resource that has changed, you could store these ID from the creation of the channel, you could use x-goog-channel-id or the x-goog-resource-id to compare them to your local store.

    You local store might be a simple JSON:

    {
        '2iPJp6kI2131231245543aQ_rIFGwE' : '[FILE_ID]'
    }
    

    Or you can just parse the x-goog-resource-uri to obtain the ID as you have already done.

    To subsequently get more data about revisions and version-dependent/independent data, you would just use normal GET requests to the Drive API upon receiving a push notification.

    The Sample you linked

    This shows the watch request response:

    {
      "kind": "api#channel",
      "id": "01234567-89ab-cdef-0123456789ab"", // ID you specified for this channel.
      "resourceId": "o3hgv1538sdjfh", // ID of the watched resource.
      "resourceUri": "https://www.googleapis.com/drive/v3/files/o3hgv1538sdjfh", // Version-specific ID of the watched resource.
      "token": "target=myApp-myFilesChannelDest", // Present only if one was provided.
      "expiration": 1426325213000, // Actual expiration time as Unix timestamp (in ms), if applicable.
    }
    

    This is the one-time response that you get when you create the notification channel. It is not the format of the push notifications that you get when the resource changes.

    Docs