推送通知

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

概览

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", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myFilesChannelDest", // (Optional) Your channel token.
  "params": {
    "ttl": 3600 // (Optional) Your requested time-to-live for this channel.
  }
}

使用 domainevent 参数指定您想接收与哪些事件相关的网域和类型。

针对客户的用户资源的所有监视请求都采用以下常规形式:

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", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myFilesChannelDest", // (Optional) Your channel token.
  "params": {
    "ttl": 3600 // (Optional) Your requested time-to-live for this channel.
  }
}

使用 customerevent 参数指定客户 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-Id HTTP 标头中。

  • 设置为 web_hook 值的 type 属性字符串。

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

    请注意,只有当您的网络服务器上安装了有效的 SSL 证书时,Directory API 才能向此 HTTPS 地址发送通知。无效的证书包括:

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

可选属性

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

  • token 属性,用于指定要用作通道令牌的任意字符串值。您可以将通知渠道令牌用于各种目的。例如,您可以使用令牌验证传入的每条消息是否都属于应用创建的通道(确保通知不被假冒),或者根据此通道的用途将消息路由到您应用中的正确目标位置。长度上限:256 个字符。

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

    如果您使用通知渠道令牌,我们建议您执行以下操作:

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

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

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

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

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

观看回复

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

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

{
  "kind": "api#channel",
  "id": "01234567-89ab-cdef-0123456789ab", // ID you specified for this channel.
  "resourceId": "B4ibMJiIhTjAQd7Ff2K2bexk8G4", // ID of the watched resource.
  "resourceUri": "https://admin.googleapis.com/admin/directory/v1/users?domain=domain&event=event", // Version-specific ID of the watched resource.
  "token": "target=myApp-myFilesChannelDest", // Present only if one was provided.
  "expiration": 1384823632000, // Actual expiration time as Unix timestamp (in ms), if applicable.
}

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

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

要详细了解该响应,请参阅 API 参考中 Users 资源的 watch 方法。

同步邮件

创建通知渠道以监控资源后,Directory API 会发送 sync 消息,指示通知已开始。这些消息的 X-Goog-Resource-State HTTP 标头值为 sync。由于网络计时问题,您甚至有可能在收到 watch 方法响应之前就收到 sync 消息。

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

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

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

接收通知

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

解读通知消息格式

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

标头

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

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

面向用户的通知消息会在请求正文中包含以下信息:

媒体资源 说明
kind 将其标识为用户资源。值:固定字符串“admin#directory#user”。
id 用户资源的唯一标识符。
etag 通知消息的 eSIM 卡。与 User 资源的 ETag 不同。
primaryEmail 用户的主电子邮件地址。

示例

User 资源事件的通知消息采用常规格式:

POST https://mydomain.com/notifications // Your receiving URL.
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 // Your receiving URL.
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"
}

有关通知的操作

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

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

停止通知

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

https://www.googleapis.com/admin/directory_v1/channels/stop

此方法要求您至少提供频道的 idresourceId 属性,如以下示例所示。请注意,如果 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"
}