Google Drive API推送通知无法停止/取消

Pri*_*ner 3 google-drive-api google-api-nodejs-client

我正在观看Drive资源.设置手表(使用带有node.js和drive.file.watch的googleapis 0.2.13-alpha客户端):

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);

Run Code Online (Sandbox Code Playgroud)

在此之后,我得到了回应

{ 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' }
Run Code Online (Sandbox Code Playgroud) 以及带有以下标题的同步回调
  '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)

但是,有几个问题:

  • 这两者返回的resource-id与我订阅watch时传递的fileId不匹配.它确实匹配resource-uri中给出​​的ID
  • 尝试使用此处返回的resourceID或我订阅时传递的fileId,当我尝试停止通道时返回错误.

为drive.channel.stop指定的错误取决于我如何进行调用.如果我使用Channel:Stop页面底部的API Explorer,为resourceId参数提供resourceId或fileId,我得到


404 Not Found

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "Channel not found"
   }
  ],
  "code": 404,
  "message": "Channel not found"
 }
}
Run Code Online (Sandbox Code Playgroud)

如果我将node.js库与此代码一起使用:

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);
Run Code Online (Sandbox Code Playgroud)

我收到了错误

{ code: 500,
  message: 'Internal Error',
  data: 
   [ { domain: 'global',
       reason: 'internalError',
       message: 'Internal Error' } ] }
Run Code Online (Sandbox Code Playgroud) 我怀疑它与Bug 59有关,它有一个解决方法(这是我上面使用的黑客代码),但本周某些时候应该有修复,我明白了.

所以我把它改成了这个代码,它解决了files.watch的bug:


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;
};
Run Code Online (Sandbox Code Playgroud)

但是我得到了相同的500错误.

关于我可能做错了什么或者如何调试我可能出错的地方的任何想法?

Jun*_*wak 5

  1. 推送通知旨在监视任何api资源,尽管它目前仅支持更改和文件.因此,它需要所有资源类型的唯一resourceId.这就是为什么他们的resourceId不等于fileId的原因.

  2. 确认确实会返回有关正在观看哪个文件的信息.检查您的回复标题.此外,如果需要,您可以使用令牌来保存特定于频道的信息.

  3. 如果您使用的是API资源管理器,则无法取消订阅该频道,因为如您所知,推送通知需要通过apis控制台对网址进行额外验证,而apis资源管理器未经过身份验证才能访问您的通知.它是出于安全原因的预期工作.我将报告此问题,以阻止人们对此感到困惑.

  4. fileId不会去请求正文.它应该是参数之一.此外,您应该向Channels.stop()请求取消订阅.像这样的东西:

订阅代码:

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

取消订阅的代码

var request = client.drive.channels.stop({'id': channelId, 'resourceId':resourceId});
Run Code Online (Sandbox Code Playgroud)