获取推送通知

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

概览

Google 日历 API 提供推送通知,让您可以监控资源的变化。您可以使用此功能来提高应用的性能。 这样一来,您就不必轮询资源来确定资源是否发生了变化,从而避免了额外的网络和计算 费用。 每当受监控的资源发生变化时,Google 日历 API 都会通知您的 应用。

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

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

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

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

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

目前,Google 日历 API 支持针对 ACLCalendarListEventsSettings 资源的更改发送通知。

创建通知渠道

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

发出监控请求

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

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

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

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

示例

开始监控给定日历上的一系列活动的变化:

POST https://www.googleapis.com/calendar/v3/calendars/my_calendar@gmail.com/events/watch
Authorization: Bearer auth_token_for_current_user
Content-Type: application/json

{
  "id": "01234567-89ab-cdef-0123456789ab",
  "type": "web_hook",
  "address": "https://mydomain.com/notifications",
  ...
  "token": "target=myApp-myCalendarChannelDest",
  "expiration": 1426325213000
}

在请求正文中,提供渠道 idtype(设置为 web_hook)以及 address 中的接收网址。 您还可以选择性地提供:

  • 一个 token,用作渠道令牌。
  • 一个 expiration 时间(以毫秒为单位),用作请求的渠道到期时间。

必要属性

对于每个 watch 请求,您都必须提供以下字段:

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

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

  • 一个 type 属性字符串,设置为值 web_hook

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

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

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

可选属性

您还可以在 watch 请求中指定以下可选字段:

  • 一个 token 属性,用于指定要用作渠道令牌的任意字符串 值。您可以使用通知渠道 令牌来实现各种用途。例如,您可以使用该 令牌来验证每条收到的消息是否适用于您的 应用创建的渠道,以确保通知不是 仿冒的;或者根据此渠道的用途,将消息路由到 应用中的正确目标。最长长度: 256 个字符。

    该令牌包含在您的应用为此渠道收到的每条通知消息的 X-Goog-Channel-Token HTTP 标头中。

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

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

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

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

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

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

监控响应

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

监控响应的消息正文提供了有关您刚刚创建的 通知渠道的信息,如以下示例所示。

{
  "kind": "api#channel",
  "id": "01234567-89ab-cdef-0123456789ab",
  "resourceId": "o3hgv1538sdjfh",
  "resourceUri": "https://www.googleapis.com/calendar/v3/calendars/my_calendar@gmail.com/events",
  "token": "target=myApp-myCalendarChannelDest",
  "expiration": 1426325213000
}

响应正文提供了渠道详细信息,例如:

  • kind:标识此资源为 API 渠道资源。
  • id:您为此渠道指定的 ID。
  • resourceId:受监控资源的 ID。
  • resourceUri:受监控资源的特定于版本的 ID。
  • token:请求正文中提供的令牌。
  • expiration:渠道到期时间,以 Unix 时间戳(以毫秒为单位)表示。

除了您作为请求的一部分发送的属性之外,返回的信息还包括 resourceIdresourceUri,用于标识在此通知渠道上受监控的资源。

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

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

同步消息

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

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

Google 日历 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 日历 API 内部限制或默认值决定(以限制性更强的值为准)。渠道的到期时间(如果有)会作为 Unix 时间戳(以毫秒为单位)包含在 watch 方法返回的信息中。此外,到期日期和时间(以人类可读的格式)也会包含在您的应用为此渠道收到的每条通知消息的 X-Goog-Channel-Expiration HTTP 标头中。

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

接收通知

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

解读通知消息格式

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

标头

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

标头 说明
始终存在
X-Goog-Channel-ID 您提供的用于标识此 通知渠道的 UUID 或其他唯一字符串。
X-Goog-Message-Number 用于标识此通知 渠道的此消息的整数。sync 消息的值始终为 1。渠道上每条后续消息的消息 编号都会增加,但消息 编号不是连续的。
X-Goog-Resource-ID 用于标识受监控资源的不透明值。此 ID 在不同 API 版本中是 稳定的。
X-Goog-Resource-State 触发通知的新资源状态。 可能的值: syncexistsnot_exists
X-Goog-Resource-URI 受监控资源的特定于 API 版本的标识符。
有时存在
X-Goog-Channel-Expiration 通知渠道到期日期和时间,以 人类可读的格式表示。仅在定义时存在。
X-Goog-Channel-Token 由您的应用设置的通知渠道令牌,您可以使用该令牌来验证通知来源。 仅在 定义时存在。

Calendar API 发布到接收网址的通知消息不包含消息正文。这些消息不包含有关更新资源的具体信息;您必须进行另一次 API 调用才能查看完整的更改详细信息。

示例

针对修改后的一系列活动的更改通知消息:

POST https://mydomain.com/notifications
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/calendar/v3/calendars/my_calendar@gmail.com/events
X-Goog-Resource-State:  exists
X-Goog-Message-Number: 10

有关通知的操作

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

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

了解 Google 日历 API 通知事件

本部分详细介绍了在使用 Google 日历 API 的推送通知时可以收到的通知消息。

X-Goog-Resource-State 适用对象 传送时间
sync ACL、日历列表、活动、设置。 已成功创建新渠道。现在可以接收通知了。
exists ACL、日历列表、活动、设置。 资源发生了变化。可能的更改包括创建新资源,或修改或删除现有资源。

停止通知

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

https://www.googleapis.com/workspace/calendar/api/v3/reference/channels/stop

此方法要求您至少提供渠道的 idresourceId 属性,如以下 示例所示。请注意,如果 Google 日历 API 有多种具有 资源,这些资源具有 watch 方法,则只有一个 stop 方法。

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

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

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

POST https://www.googleapis.com/workspace/calendar/api/v3/reference/channels/stop
  
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json

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