资源更改通知

本文档介绍了如何使用推送通知在资源发生更改时通知您的应用。

概览

Google Drive API 提供推送通知,让您可以监控资源的变化。您可以使用此功能来提升应用性能。借助此功能,您可以避免因轮询资源以确定它们是否已更改而产生的额外网络和计算费用。 每当受监控的资源发生变化时,Google Drive API 都会通知您的应用。

如需使用推送通知,您必须执行以下两项操作:

  • 设置接收网址或“网络钩子”回调接收器。

    这是一个 HTTPS 服务器,用于处理在资源发生更改时触发的 API 通知消息。

  • 为要监控的每个资源端点设置一个(通知渠道)。

    渠道用于指定通知消息的路由信息。在设置渠道时,您必须指定要接收通知的具体网址。每当频道的资源发生更改时,Google Drive API 都会向该网址发送一条通知消息作为 POST 请求。

目前,Google Drive API 支持针对 fileschanges 方法的更改发送通知。

创建通知渠道

如需请求推送通知,您必须为要监控的每个资源设置通知渠道。设置好通知渠道后,当任何受监控的资源发生更改时,Google Drive API 都会通知您的应用。

发出手表请求

每个可监控的 Google 云端硬盘 API 资源都有一个关联的 watch 方法,其 URI 采用以下格式:

https://www.googleapis.com/API_NAME/API_VERSION/RESOURCE_PATH/watch

如需为有关特定资源更改的消息设置通知渠道,请向相应资源的 watch 方法发送 POST 请求。

每个通知渠道都与特定用户和特定资源(或一组资源)相关联。除非当前用户或服务账号拥有或有权访问相应资源,否则 watch 请求不会成功。

示例

以下代码示例展示了如何使用 channels 资源通过 files.watch 方法开始监听单个 files 资源的变化:

POST https://www.googleapis.com/drive/v3/files/fileId/watch
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json

{
  "id": "01234567-89ab-cdef-0123456789ab", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myFilesChannelDest", // (Optional) Your files channel token.
  "expiration": 1426325213000 // (Optional) Your requested channel expiration date and time.
}

以下代码示例展示了如何使用 channels 资源通过 changes.watch 方法开始监听所有 changes

POST https://www.googleapis.com/drive/v3/changes/watch
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json

{
  "id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a77", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myChangesChannelDest", // (Optional) Your changes channel token.
  "expiration": 1426325213000 // (Optional) Your requested channel expiration date and time.
}

必要属性

您必须在每个 watch 请求中提供以下字段:

  • 一个 id 属性字符串,用于在您的项目中唯一标识此新通知渠道。我们建议使用通用唯一标识符 (UUID) 或任何类似的唯一字符串。长度上限:64 个字符。

    您设置的 ID 值会回显在您为此渠道收到的每条通知消息的 X-Goog-Channel-Id HTTP 标头中。

  • 设置为值 web_hooktype 属性字符串。

  • 一个 address 属性字符串,设置为用于监听和响应此通知渠道的通知的网址。这是您的 webhook 回调网址,必须使用 HTTPS。

    请注意,只有在您的 Web 服务器上安装了有效的 SSL 证书后,Google Drive API 才能向此 HTTPS 地址发送通知。无效的证书包括:

    • 自签发证书
    • 由不受信任的来源签发的证书
    • 已被撤消的证书
    • 证书的主题与目标主机名不匹配。

可选属性

您还可以通过 watch 请求指定以下选填字段:

  • 一种 token 属性,用于指定要用作渠道令牌的任意字符串值。您可以将通知渠道令牌用于各种用途。例如,您可以使用该令牌来验证每条传入的消息是否是针对您的应用创建的渠道的,以确保通知未被欺骗;或者根据此渠道的用途,将消息路由到应用内的正确目的地。长度上限:256 个字符。

    令牌包含在您的应用针对相应频道收到的每条通知消息的 X-Goog-Channel-Token HTTP 标头中。

    如果您使用通知渠道令牌,我们建议您:

    • 使用可扩展的编码格式,例如网址查询参数。示例:forwardTo=hr&createdBy=mobile

    • 请勿包含 OAuth 令牌等敏感数据。

  • 一个 expiration 属性字符串,设置为您希望 Google Drive API 停止为此通知渠道发送消息的日期和时间(以毫秒为单位)的 Unix 时间戳

    如果某个渠道有过期时间,则在您的应用针对该渠道收到的每条通知消息中,该过期时间会以 X-Goog-Channel-Expiration HTTP 标头的值(采用人类可读的格式)的形式包含在内。

如需详细了解请求,请参阅 API 参考文档中 fileschanges 方法的 watch 方法。

手表回答

如果 watch 请求成功创建了通知渠道,则返回 HTTP 200 OK 状态代码。

手表响应的消息正文会提供有关您刚刚创建的通知渠道的信息,如下例所示。

{
  "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 date and time as UNIX timestamp (in milliseconds), if applicable.
}

除了您在请求中发送的属性之外,返回的信息还包括 resourceIdresourceUri,用于标识此通知渠道上正在观看的资源。

您可以将返回的信息传递给其他通知渠道操作,例如当您想停止接收通知时。

如需详细了解响应,请参阅 API 参考文档中 fileschanges 方法的 watch 方法。

同步消息

创建用于监控资源的通知渠道后,Google Drive API 会发送 sync 消息,表明通知即将开始。这些消息的 X-Goog-Resource-State HTTP 标头值为 sync。由于网络时序问题,即使在收到 watch 方法响应之前,也可能会收到 sync 消息。

您可以放心地忽略 sync 通知,但也可以使用它。例如,如果您决定不再保留该渠道,可以在调用中通过 X-Goog-Channel-IDX-Goog-Resource-ID停止接收通知。您还可以使用 sync 通知执行一些初始化操作,为后续事件做好准备。

Google Drive API 发送给接收网址的 sync 消息的格式如下所示。

POST https://mydomain.com/notifications // Your receiving URL.
X-Goog-Channel-ID: channel-ID-value
X-Goog-Channel-Token: channel-token-value
X-Goog-Channel-Expiration: expiration-date-and-time // In human-readable format. Present only if the channel expires.
X-Goog-Resource-ID: identifier-for-the-watched-resource
X-Goog-Resource-URI: version-specific-URI-of-the-watched-resource
X-Goog-Resource-State: sync
X-Goog-Message-Number: 1

同步消息的 X-Goog-Message-Number HTTP 标头值始终为 1。此渠道的每个后续通知的消息编号都比前一个通知的消息编号大,但消息编号不会是连续的。

续订通知渠道

通知渠道可以设置过期时间,该值由您的请求或任何 Google Drive API 内部限制或默认值确定(以限制性更强的值为准)。如果频道有失效时间,该时间会以 watch 方法返回的信息中的 Unix 时间戳(以毫秒为单位)的形式包含在其中。此外,您的应用针对相应渠道收到的每条通知消息的 X-Goog-Channel-Expiration HTTP 标头中都包含到期日期和时间(采用人类可读的格式)。

目前,没有自动续订通知渠道的方法。当渠道即将过期时,您必须通过调用 watch 方法将其替换为新渠道。与往常一样,您必须为新渠道的 id 属性使用唯一值。请注意,同一资源可能会出现两个通知渠道同时处于有效状态的“重叠”时间段。

接收通知

每当受监控的资源发生变化时,您的应用都会收到一条描述相应变化的通知消息。Google Drive API 会将这些消息作为 HTTPS POST 请求发送到您为相应通知渠道指定的 address 属性对应的网址。

解读通知消息格式

所有通知消息都包含一组带有 X-Goog- 前缀的 HTTP 标头。 某些类型的通知还可以包含消息正文。

标头

Google Drive API 发布到接收网址的通知消息包含以下 HTTP 标头:

标题 说明
始终存在
X-Goog-Channel-ID 您提供的用于标识相应通知渠道的 UUID 或其他唯一字符串。
X-Goog-Message-Number 用于标识相应通知渠道的此消息的整数。对于 sync 消息,值始终为 1。频道上每条后续消息的消息编号都会递增,但这些编号不是连续的。
X-Goog-Resource-ID 用于标识所监控资源的不透明值。此 ID 在各个 API 版本中保持稳定。
X-Goog-Resource-State 触发通知的新资源状态。 可能的值: syncaddremoveupdatetrashuntrashchange
X-Goog-Resource-URI 所监控资源的特定于 API 版本的标识符。
有时存在
X-Goog-Changed 有关变更的其他详细信息。 可能的值: content parents childrenpermissions 。 不随 sync 消息提供。
X-Goog-Channel-Expiration 通知渠道的到期日期和时间,以人类可读的格式表示。仅在定义时存在。
X-Goog-Channel-Token 由您的应用设置的通知渠道令牌,可用于验证通知来源。仅在定义时存在。

fileschanges 的通知消息为空。

示例

针对不包含请求正文的 files 资源的更改通知消息:

POST https://mydomain.com/notifications // Your receiving URL.
Content-Type: application/json; utf-8
Content-Length: 0
X-Goog-Channel-ID: 4ba78bf0-6a47-11e2-bcfd-0800200c9a66
X-Goog-Channel-Token: 398348u3tu83ut8uu38
X-Goog-Channel-Expiration: Tue, 19 Nov 2013 01:13:52 GMT
X-Goog-Resource-ID:  ret08u3rv24htgh289g
X-Goog-Resource-URI: https://www.googleapis.com/drive/v3/files/ret08u3rv24htgh289g
X-Goog-Resource-State:  update
X-Goog-Changed: content,properties
X-Goog-Message-Number: 10

针对 changes 资源的更改通知消息,包含请求正文:

POST https://mydomain.com/notifications // Your receiving URL.
Content-Type: application/json; utf-8
Content-Length: 118
X-Goog-Channel-ID: 8bd90be9-3a58-3122-ab43-9823188a5b43
X-Goog-Channel-Token: 245t1234tt83trrt333
X-Goog-Channel-Expiration: Tue, 19 Nov 2013 01:13:52 GMT
X-Goog-Resource-ID:  ret987df98743md8g
X-Goog-Resource-URI: https://www.googleapis.com/drive/v3/changes
X-Goog-Resource-State:  changed
X-Goog-Message-Number: 23

{
  "kind": "drive#changes"
}

有关通知的操作

如需指明成功,您可以返回以下任何状态代码:200201202204102

如果您的服务使用 Google 的 API 客户端库并返回 500502503504,则 Google Drive API 会使用指数退避进行重试。 所有其他返回状态代码均被视为消息失败。

了解 Google Drive API 通知事件

本部分详细介绍了将推送通知与 Google Drive API 搭配使用时可能会收到的通知消息。

X-Goog-Resource-State 适用对象 递送时间
sync fileschanges 已成功创建频道。您应该会开始收到相关通知。
add files 创建或共享了资源。
remove files 现有资源已被删除或停止分享。
update files 资源的 1 项或多项属性(元数据)已更新。
trash files 某项资源已移至回收站。
untrash files 资源已从回收站中移除。
change changes 已添加一个或多个更改日志项。

对于 update 事件,可能会提供 X-Goog-Changed HTTP 标头。该标头包含一个以英文逗号分隔的列表,用于描述已发生的更改类型。

更改类型 含义
content 资源内容已更新。
properties 一个或多个资源属性已更新。
parents 已添加或移除一个或多个资源父级。
children 已添加或移除了一个或多个资源子项。
permissions 资源权限已更新。

使用 X-Goog-Changed 标头的示例:

X-Goog-Resource-State: update
X-Goog-Changed: content, permissions

停止通知

expiration 属性用于控制通知何时自动停止。您可以在特定渠道过期之前选择停止接收该渠道的通知,方法是调用以下 URI 中的 stop 方法:

https://www.googleapis.com/drive/v3/channels/stop

此方法要求您至少提供频道的 idresourceId 属性,如下例所示。请注意,如果 Google Drive API 有多种具有 watch 方法的资源类型,则只有一种 stop 方法。

只有拥有相应权限的用户才能停止频道。具体而言:

  • 如果频道是由常规用户账号创建的,则只有创建该频道的同一客户端(由身份验证令牌中的 OAuth 2.0 客户端 ID 标识)的同一用户才能停止该频道。
  • 如果频道是由服务账号创建的,则同一客户端中的任何用户都可以停止该频道。

以下代码示例展示了如何停止接收通知:

POST https://www.googleapis.com/drive/v3/channels/stop
  
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json

{
  "id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a66",
  "resourceId": "ret08u3rv24htgh289g"
}