Question

I am watching a Drive resource. Setting up the watch (using the googleapis 0.2.13-alpha client with node.js and drive.file.watch):

exports.subscribeDriveCallbacksCmd = function( user, fileId ){
  var userId = user.id;
  var baseUrl = exports.BASE_URL;
  var subscribeUrl = baseUrl+"/incoming/file";
  var watchId = 'id-'+fileId+'-'+(new Date()).getTime();
  var subscription = {
    id: watchId,
    token: userId+':'+fileId,
    type: 'web_hook',
    address: subscribeUrl,
    params:{
      ttl: 600
    }
  };
  var params = {
    fileId: fileId
  };

//var cmd = client.drive.files.watch( params, subscription );

// FIXME - Hack around bug in RPC implememntation var hack = {channel:subscription}; for( var key in params ){ hack[key] = params[key]; } var cmd = client.drive.files.watch( hack );

return cmd; };

var cmd = exports.subscribeDriveCallbacksCmd( user, '0ZZuoVaqdWGhpUk9PZZ' ); var batch = client.newBatchRequest(); batch.add(cmd); batch.withAuthClient(user.auth).execute(cb);

After this, I'm getting a response of

{ kind: 'api#channel',
    id: 'id-0ZZuoVaqdWGhpUk9PZZ-1374536746592',
    resourceId: 'WT6g4bx-4or2kPWsL53z7YxZZZZ',
    resourceUri: 'https://www.googleapis.com/drive/v2/files/0AHuoVaqdWGhpUkZZZZ?updateViewedDate=false&alt=json',
    token: '101852559274654726533:0ZZuoVaqdWGhpUk9PZZ',
    expiration: '1374537347934' }
and a sync callback with the following headers
  'x-goog-channel-id': 'id-0ZZuoVaqdWGhpUk9PZZ-1374536746592',
  'x-goog-channel-expiration': 'Mon, 22 Jul 2013 23:55:47 GMT',
  'x-goog-resource-state': 'sync',
  'x-goog-message-number': '1',
  'x-goog-resource-id': 'WT6g4bx-4or2kPWsL53z7YxZZZZ',
  'x-goog-resource-uri': 'https://www.googleapis.com/drive/v2/files/0AHuoVaqdWGhpUkZZZZ?updateViewedDate=false&alt=json',
  'x-goog-channel-token': '101852559274654726533:0ZZuoVaqdWGhpUk9PZZ',
  'user-agent': 'APIs-Google; (+http://code.google.com/apis)

There are several problems with this, however:

  • The resource-id returned by both of these do not match the fileId passed when I subscribed to the watch. It does match the ID given in the resource-uri
  • Trying to use either the resourceID returned here, or the fileId passed when I subscribed, returns an error when I try to stop the channel.

The error given for drive.channel.stop varies depending on how I do the call. If I use the API Explorer at the bottom of the Channel: Stop page, providing either the resourceId or the fileId for the resourceId parameter, I get


404 Not Found

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "Channel not found"
   }
  ],
  "code": 404,
  "message": "Channel not found"
 }
}

If I use the node.js library with this code:

exports.cancelDriveCallbacksCmd = function( watchId, fileId, resourceId ){
  var body = {
    id: watchId,
    resourceId: resourceId
  };
  var cmd = client.drive.channels.stop( body );
  return cmd;
};
var cmd = exports.cancelDriveCallbacksCmd( 'id-0ZZuoVaqdWGhpUk9PZZ-1374536746592', '0ZZuoVaqdWGhpUk9PZZ', 'WT6g4bx-4or2kPWsL53z7YxZZZZ' );
var batch = client.newBatchRequest();
batch.add(cmd);
batch.withAuthClient(user.auth).execute(cb);

I get the error

{ code: 500,
  message: 'Internal Error',
  data: 
   [ { domain: 'global',
       reason: 'internalError',
       message: 'Internal Error' } ] }
which I suspected was related to Bug 59 which has a workaround (which was the hack code I was using above) but should have the fix in place sometime this week, I understand.

So I changed it to this code, which worked around the bug for files.watch:


exports.cancelDriveCallbacksCmd = function( watchId, fileId, resourceId ){
  var params = {};
  var body = {
    id: watchId,
    resourceId: resourceId,
    fileId: fileId
  };

  //var cmd = client.drive.channels.stop( params, body );

  // FIXME - hack around bug in RPC implementation
  var hack = {channel:body};
  for( var key in params ){
    hack[key] = params[key];
  }
  var cmd = client.drive.channels.stop( hack );
  console.log( 'cancelDriveCallbacksCmd', hack );

  return cmd;
};

But I get the same 500 error.

Any thoughts about what I might be doing wrong or how to even go about debugging where I might be going wrong with it?

Was it helpful?

Solution

  1. Push notification is designed to watch any api resource, although it only supports Changes and Files for now. Thus, it needs unique resourceId for all resource type. That is the reason why they have resourceId that is not equal to fileId.

  2. Confirmations do come back with info about which file it is watching. Check header of your response. Also, you can make use of token to save channel specific information if you want.

  3. If you are using API explorer, you cannot unsubscribe from the channel because as you know, push notification requires additional verification of url through apis console and apis explorer is not authenticated to access your notification. It is working as intended by security reason. I will report about this issue to stop people from getting confused with this.

  4. fileId doesn't go to request body. It should be one of the parameters. Also, you should make request to Channels.stop() to unsubscribe. Something like this:

Code to subscribe:

var channel= {
  'id': 'yourchannelid',
  'type': 'web_hook',
  'address': 'https://notification.endpoint'
};
var request = client.drive.files.watch({'fileId': fileId, 'channel':channel});

Code to unsubscribe

var request = client.drive.channels.stop({'id': channelId, 'resourceId':resourceId});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top