本文档介绍了如何使用推送通知在资源发生更改时通知应用。
概览
Directory API 提供推送通知,让您可以监控资源的变化。您可以使用此功能来提升应用性能。这样一来,您无需轮询资源来确定它们是否已更改,从而避免了额外的网络和计算费用。 每当受监控的资源发生变化时,Directory API 都会通知您的应用。
如需使用推送通知,您必须执行以下两项操作:
设置接收网址或“网络钩子”回调接收器。
这是一个 HTTPS 服务器,用于处理在资源发生更改时触发的 API 通知消息。
为要监控的每个资源端点设置一个(通知渠道)。
渠道用于指定通知消息的路由信息。在设置渠道时,您必须指定要接收通知的具体网址。每当频道的资源发生变化时,Directory API 都会向该网址发送一条通知消息,作为
POST请求。
目前,Directory API 支持针对 Users 资源所做更改的通知。
创建通知渠道
如需请求推送通知,您必须为要监控的每个资源设置通知渠道。设置通知渠道后,当任何受监控的资源发生更改时,Directory API 都会通知您的应用。
发出观看请求
每个可监控的 Directory API 资源都有一个关联的 watch 方法,其 URI 格式如下:
https://www.googleapis.com/API_NAME/API_VERSION/RESOURCE_PATH/watch
如需为有关特定资源更改的消息设置通知渠道,请向相应资源的 watch 方法发送 POST 请求。
每个通知渠道都与特定用户和特定资源(或一组资源)相关联。除非当前用户或服务账号拥有相应资源或有权访问相应资源,否则 watch 请求不会成功。
示例
针对单个网域的 User 资源的所有手表请求都具有以下通用格式:
POST https://admin.googleapis.com/admin/directory/v1/users/watch?domain=domain&event=event
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-myFilesChannelDest",
"params": {
"ttl": 3600
}
}在请求正文中,提供您的频道 id、type(设置为 web_hook)以及 address 中的接收网址。您还可以选择提供以下信息:
- 用作渠道令牌的
token。 params中的ttl,用于请求相应频道的存留时间(以秒为单位)。
使用 domain 和 event 参数指定您希望接收哪些网域和类型的事件的通知。
针对客户的 User 资源的所有监控请求都具有以下通用格式:
POST https://admin.googleapis.com/admin/directory/users/v1/watch?customer=customer&event=event
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-myFilesChannelDest",
"params": {
"ttl": 3600
}
}使用 customer 和 event 参数指定客户 Google 账号的唯一 ID 以及您希望接收通知的事件类型。
event 的可能值包括:
add:用户创建事件delete:用户删除事件makeAdmin:用户管理员状态更改事件undelete:用户取消删除事件update:用户更新事件
注意:为清晰起见,以下示例省略了请求正文。
监听网域 mydomain.com 的用户创建事件:
POST https://admin.googleapis.com/admin/directory/v1/users/watch?domain=mydomain.com&event=add
针对客户 my_customer 监控用户创建的事件:
POST https://admin.googleapis.com/admin/directory/v1/users/watch?customer=my_customer&event=add
必要属性
您必须在每个 watch 请求中提供以下字段:
-
一个
id属性字符串,用于在您的项目中唯一标识此新通知渠道。我们建议使用通用唯一标识符 (UUID) 或任何类似的唯一字符串。长度上限:64 个字符。您设置的 ID 值会回显在您为此渠道收到的每条通知消息的
X-Goog-Channel-IdHTTP 标头中。 -
设置为值
web_hook的type属性字符串。 -
一个
address属性字符串,设置为用于监听和响应相应通知渠道的通知的网址。这是您的 webhook 回调网址,必须使用 HTTPS。请注意,只有在您的 Web 服务器上安装了有效的 SSL 证书后,Directory API 才能向此 HTTPS 地址发送通知。无效的证书包括:
- 自签发证书
- 由不受信任的来源签发的证书
- 已被撤消的证书
- 证书的主题与目标主机名不匹配。
可选属性
您还可以在 watch 请求中指定以下可选字段:
-
一种
token属性,用于指定要用作渠道令牌的任意字符串值。您可以将通知渠道令牌用于各种用途。例如,您可以使用该令牌来验证每条传入的消息是否是针对您的应用创建的渠道的,以确保通知未被欺骗;或者根据此渠道的用途,将消息路由到应用内的正确目的地。长度上限:256 个字符。令牌包含在您的应用针对相应频道收到的每条通知消息的
X-Goog-Channel-TokenHTTP 标头中。如果您使用通知渠道令牌,我们建议您:
使用可扩展的编码格式,例如网址查询参数。示例:
forwardTo=hr&createdBy=mobile请勿包含 OAuth 令牌等敏感数据。
-
一个
expiration属性字符串,设置为您希望 Directory API 停止为此通知渠道发送消息的日期和时间(以毫秒为单位)的 Unix 时间戳。如果渠道具有过期时间,则在您的应用针对相应渠道收到的每条通知消息中,该过期时间会以
X-Goog-Channel-ExpirationHTTP 标头的值(采用人类可读的格式)的形式包含在内。
如需详细了解该请求,请参阅 API 参考文档中 Users 资源的 watch 方法。
观看回答
如果 watch 请求成功创建了通知渠道,则返回 HTTP 200 OK 状态代码。
手表响应的消息正文会提供有关您刚刚创建的通知渠道的信息,如下例所示。
{
"kind": "api#channel",
"id": "01234567-89ab-cdef-0123456789ab",
"resourceId": "B4ibMJiIhTjAQd7Ff2K2bexk8G4",
"resourceUri": "https://admin.googleapis.com/admin/directory/v1/users?domain=domain&event=event",
"token": "target=myApp-myFilesChannelDest",
"expiration": 1384823632000
}响应正文提供频道详细信息,例如:
id:您为此渠道指定的 ID。resourceId:受监控资源的 ID。resourceUri:所监控资源的特定于版本的 ID。token:请求正文中提供的令牌。expiration:渠道到期时间,以毫秒为单位的 Unix 时间戳。
除了您在请求中发送的属性之外,返回的信息还包括 resourceId 和 resourceUri,用于标识此通知渠道上正在监控的资源。
您可以将返回的信息传递给其他通知渠道操作,例如当您想停止接收通知时。
如需详细了解响应,请参阅 API 参考文档中 Users 资源的 watch 方法。
同步消息
创建用于监控资源的通知渠道后,Directory API 会发送 sync 消息,表明通知即将开始。这些消息的 X-Goog-Resource-State HTTP 标头值为 sync。由于网络时序问题,即使在收到 watch 方法响应之前,您也可能会收到 sync 消息。
您可以放心地忽略 sync 通知,但也可以使用它。例如,如果您决定不再保留该渠道,可以在调用 stop receiving notifications 时使用 X-Goog-Channel-ID 和 X-Goog-Resource-ID 值。您还可以使用 sync 通知进行一些初始化,为后续事件做好准备。
目录 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。此渠道的每个后续通知的消息编号都比前一个通知的消息编号大,但消息编号不会是连续的。
续订通知渠道
通知渠道可以具有到期时间,该值由您的请求或任何 Directory API 内部限制或默认值确定(以限制性更强的值为准)。如果频道有失效时间,该时间会以 watch 方法返回的信息中的 Unix 时间戳(以毫秒为单位)的形式包含在其中。此外,您的应用针对相应频道收到的每条通知消息的 X-Goog-Channel-Expiration HTTP 标头中都包含到期日期和时间(采用人类可读的格式)。
目前,没有自动续订通知渠道的方法。当渠道即将过期时,您必须通过调用 watch 方法将其替换为新渠道。与往常一样,您必须为新渠道的 id 属性使用唯一值。请注意,同一资源可能会出现两个通知渠道同时处于有效状态的“重叠”时间段。
接收通知
每当受监控的资源发生变化时,您的应用都会收到一条描述相应变化的通知消息。Directory API 会将这些消息作为 HTTPS POST 请求发送到您为相应通知渠道指定的 address 属性对应的网址。
解读通知消息格式
所有通知消息都包含一组带有 X-Goog- 前缀的 HTTP 标头。
某些类型的通知还可以包含消息正文。
标头
Directory API 发布到接收网址的通知消息包含以下 HTTP 标头:
| 标题 | 说明 |
|---|---|
| 始终存在 | |
|
您提供的用于标识相应通知渠道的 UUID 或其他唯一字符串。 |
|
用于标识相应通知渠道的相应消息的整数。对于 sync 消息,值始终为 1。频道上每条后续消息的编号都会递增,但这些编号不是连续的。 |
|
用于标识所监控资源的不透明值。此 ID 在各个 API 版本中保持稳定。 |
|
触发通知的新资源状态。
可能的值:
sync 或事件名称。
|
|
所监控资源的特定于 API 版本的标识符。 |
| 有时存在 | |
|
通知渠道的过期日期和时间,以人类可读的格式表示。仅在定义时存在。 |
|
由您的应用设置的通知渠道令牌,可用于验证通知来源。仅在定义时存在。 |
针对用户的通知消息在请求正文中包含以下信息:
| 属性 | 说明 |
|---|---|
kind |
将此标识为 User 资源。值:固定字符串“admin#directory#user”。 |
id |
用户资源的唯一标识符。 |
etag |
通知消息的 ETag。与 User 资源的 ETag 不同。 |
primaryEmail |
用户的主邮箱。 |
示例
针对 User 资源事件的通知消息具有以下一般形式:
POST https://mydomain.com/notifications
Content-Type: application/json; utf-8
Content-Length: 0
X-Goog-Channel-ID: directoryApiId
X-Goog-Channel-Token: 398348u3tu83ut8uu38
X-Goog-Channel-Expiration: Tue, 29 Oct 2013 20:32:02 GMT
X-Goog-Resource-ID: ret08u3rv24htgh289g
X-Goog-Resource-URI: https://admin.googleapis.com/admin/directory/v1/users?domain=domain&event=event
X-Goog-Resource-State: event
X-Goog-Message-Number: 10
{
"kind": "admin#directory#user",
"id": long,
"etag": string,
"primaryEmail": string
}
用户删除事件示例:
POST https://mydomain.com/notifications
Content-Type: application/json; utf-8
Content-Length: 189
X-Goog-Channel-ID: deleteChannel
X-Goog-Channel-Token: 245t1234tt83trrt333
X-Goog-Channel-Expiration: Mon, 09 Dec 2013 22:24:23 GMT
X-Goog-Resource-ID: B4ibMJiIhTjAQd7Ff2K2bexk8G4
X-Goog-Resource-URI: https://admin.googleapis.com/admin/directory/v1/users?domain=mydomain.com&event=delete&alt=json
X-Goog-Resource-State: delete
X-Goog-Message-Number: 236440
{
"kind": "admin#directory#user",
"id": "111220860655841818702",
"etag": "\"Mf8RAmnABsVfQ47MMT_18MHAdRE/evLIDlz2Fd9zbAqwvIp7Pzq8UAw\"",
"primaryEmail": "user@mydomain.com"
}
有关通知的操作
如需指明成功,您可以返回以下任一状态代码:200、201、202、204 或 102。
如果您的服务使用 Google 的 API 客户端库并返回 500、502、503 或 504,Directory API 会使用指数退避进行重试。
所有其他返回状态代码均被视为消息失败。
停止通知
expiration 属性用于控制通知何时自动停止。您可以在特定渠道过期之前选择停止接收该渠道的通知,方法是调用以下 URI 中的 stop 方法:
https://www.googleapis.com/admin/directory_v1/channels/stop
此方法要求您至少提供频道的 id 和 resourceId 属性,如下例所示。请注意,如果 Directory API 有多种具有 watch 方法的资源类型,则只有一种 stop 方法。
只有拥有相应权限的用户才能停止频道。具体而言:
- 如果频道是由常规用户账号创建的,则只有创建该频道的同一客户端(由身份验证令牌中的 OAuth 2.0 客户端 ID 标识)的同一用户才能停止该频道。
- 如果频道是由服务账号创建的,则同一客户端中的任何用户都可以停止该频道。
以下代码示例展示了如何停止接收通知:
POST https://www.googleapis.com/admin/directory_v1/channels/stop
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json
{
"id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a66",
"resourceId": "ret08u3rv24htgh289g"
}