本文档介绍了如何使用推送通知,以便在资源发生更改时通知您的应用。
概览
Google 日历 API 提供推送通知,让您可以监控资源的变化。您可以使用此功能来提高应用的性能。 这样一来,您就不必轮询资源来确定资源是否发生了变化,从而避免了额外的网络和计算 费用。 每当受监控的资源发生变化时,Google 日历 API 都会通知您的 应用。
如需使用推送通知,您必须执行以下两项操作:
设置接收网址或“网络钩子”回调接收器。
这是一个 HTTPS 服务器,用于处理在资源发生更改时 触发的 API 通知消息。
为您要监控的每个资源端点设置一个(通知渠道) 。
渠道用于指定通知 消息的路由信息。在渠道设置过程中,您必须确定要接收通知的具体网址 。每当频道的资源发生变化时, Google 日历 API 都会向该网址发送一条通知消息,作为
POST请求。
目前,Google 日历 API 支持针对 ACL、CalendarList、Events 和 Settings 资源的更改发送通知。
创建通知渠道
如需请求推送通知,您必须为要监控的每个资源设置一个通知渠道 。设置通知渠道后,每当任何受监控的资源发生变化时,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
}在请求正文中,提供渠道 id、type(设置为 web_hook)以及 address 中的接收网址。
您还可以选择性地提供:
- 一个
token,用作渠道令牌。 - 一个
expiration时间(以毫秒为单位),用作请求的渠道到期时间。
必要属性
对于每个 watch 请求,您都必须提供以下字段:
-
一个
id属性字符串,用于在您的项目中唯一标识此 新通知渠道。我们建议您使用 通用唯一标识符 (UUID)或任何类似的 唯一字符串。最长长度:64 个字符。您设置的 ID 值会回显到您为此渠道收到的每条通知消息的
X-Goog-Channel-IdHTTP 标头中。 -
一个
type属性字符串,设置为值web_hook。 -
一个
address属性字符串,设置为用于监听 和响应此通知渠道的通知的网址。这是 您的网络钩子回调网址,并且必须使用 HTTPS。请注意,只有在您的 Web 服务器上安装了有效的 SSL 证书的情况下,Google 日历 API 才能向此 HTTPS 地址发送通知。无效的证书包括:
- 自签发证书
- 由不受信任的来源签发的证书
- 已被撤消的证书
- 主题与目标 主机名不匹配的证书。
可选属性
您还可以在
watch 请求中指定以下可选字段:
-
一个
token属性,用于指定要用作渠道令牌的任意字符串 值。您可以使用通知渠道 令牌来实现各种用途。例如,您可以使用该 令牌来验证每条收到的消息是否适用于您的 应用创建的渠道,以确保通知不是 仿冒的;或者根据此渠道的用途,将消息路由到 应用中的正确目标。最长长度: 256 个字符。该令牌包含在您的应用为此渠道收到的每条通知消息的
X-Goog-Channel-TokenHTTP 标头中。如果您使用通知渠道令牌,我们建议您:
使用可扩展的编码格式,例如网址查询 参数。示例:
forwardTo=hr&createdBy=mobile请勿包含 OAuth 令牌等敏感数据。
-
一个
expiration属性字符串,设置为您希望 Google 日历 API 停止为此通知渠道发送消息的日期和时间的 Unix 时间戳(以毫秒为单位)。如果渠道有到期时间,则该时间会作为
X-Goog-Channel-ExpirationHTTP 标头的值(以人类可读的格式)包含在您的应用为此渠道收到的每条通知消息中。
如需详细了解该请求,请参阅 API 参考文档中 ACL、CalendarList、Events 和 Settings 资源的 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 时间戳(以毫秒为单位)表示。
除了您作为请求的一部分发送的属性之外,返回的信息还包括 resourceId 和 resourceUri,用于标识在此通知渠道上受监控的资源。
您可以将返回的信息传递给其他通知渠道 操作,例如当您想要停止接收 通知时。
如需详细了解该响应,请参阅 API 参考文档中 ACL、CalendarList、Events 和 Settings 资源的 watch
方法。
同步消息
创建用于监控资源的通知渠道后,
Google 日历 API 会发送 sync 消息,以表明通知即将开始。这些消息的 X-Goog-Resource-State HTTP
标头值为 sync。由于网络
时序问题,您可能会在收到 watch 方法响应之前收到 sync 消息
。
您可以放心地忽略 sync 通知,但也可以
也可以使用它。例如,如果您决定不想保留
该渠道,则可以在调用中使用 X-Goog-Channel-ID 和
X-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 标头:
| 标头 | 说明 |
|---|---|
| 始终存在 | |
|
您提供的用于标识此 通知渠道的 UUID 或其他唯一字符串。 |
|
用于标识此通知
渠道的此消息的整数。sync 消息的值始终为 1。渠道上每条后续消息的消息
编号都会增加,但消息
编号不是连续的。 |
|
用于标识受监控资源的不透明值。此 ID 在不同 API 版本中是 稳定的。 |
|
触发通知的新资源状态。
可能的值:
sync、exists 或
not_exists。
|
|
受监控资源的特定于 API 版本的标识符。 |
| 有时存在 | |
|
通知渠道到期日期和时间,以 人类可读的格式表示。仅在定义时存在。 |
|
由您的应用设置的通知渠道令牌,您可以使用该令牌来验证通知来源。 仅在 定义时存在。 |
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
有关通知的操作
如需指明成功,您可以返回以下任何状态代码:
200、201、202、204 或
102。
如果您的服务使用 Google 的 API 客户端库
并返回 500、502、503 或 504,则 Google 日历 API
会使用 指数退避算法进行重试。所有其他返回状态代码都被视为消息失败。
了解 Google 日历 API 通知事件
本部分详细介绍了在使用 Google 日历 API 的推送通知时可以收到的通知消息。
| 传送时间 | ||
|---|---|---|
sync |
ACL、日历列表、活动、设置。 | 已成功创建新渠道。现在可以接收通知了。 |
exists |
ACL、日历列表、活动、设置。 | 资源发生了变化。可能的更改包括创建新资源,或修改或删除现有资源。 |
停止通知
expiration 属性用于控制通知何时自动停止。您可以选择在特定渠道到期之前停止接收该渠道的通知,方法是调用以下 URI 中的 stop 方法:
https://www.googleapis.com/workspace/calendar/api/v3/reference/channels/stop
此方法要求您至少提供渠道的
id 和 resourceId 属性,如以下
示例所示。请注意,如果 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"
}