推送通知

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

概览

Admin SDK API 提供推送通知,让您可以监控资源的变化。您可以使用此功能来提升应用性能。这样一来,您就不必轮询资源来确定它们是否已更改,从而省去额外的网络和计算费用。 每当受监控的资源发生变化时,Admin SDK API 都会通知您的应用。

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

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

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

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

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

目前,Admin SDK API 支持有关 Activities 资源发生更改的通知。

创建通知渠道

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

发出观看请求

每个可观测的 Admin SDK API 资源都有一个关联的 watch 方法,其 URI 格式如下:

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

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

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

示例

针对 Activities 资源的所有手表请求都具有以下通用格式:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/userKey or all/applications/applicationName/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-myFilesChannelDest",
  "payload": true,
  "expiration": 3600
}

请求正文具有以下属性:

  • id:用于标识相应渠道的 UUID 或类似唯一字符串。
  • type:传送机制的类型。相应字段的值必须为 web_hook
  • address:接收通知的网址。
  • token:一个任意字符串,随每条通知一起发送到目标地址,用于验证通知是否来自可信来源。
  • payload:一个布尔值标志,用于指示通知中是否应包含载荷。
  • expiration:通知渠道的存留时间(以秒为单位)。

您可以使用 userKeyapplicationNameeventNamefilters 参数仅接收特定事件、用户或应用的通知。

注意:为清晰起见,以下示例省略了请求正文。

监控所有管理员活动:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin/watch

监控所有文档活动:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/docs/watch

监控特定用户的管理员活动:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/liz@example.com/applications/admin/watch

监控特定事件,例如更改用户密码:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin/watch?eventName=CHANGE_PASSWORD

监听特定文档的更改:

POST https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/docs/watch?eventName=EDIT&filters==doc_id=123456abcdef

必要属性

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

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

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

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

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

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

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

可选属性

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

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

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

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

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

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

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

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

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

观看回答

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

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

{
  "kind": "api#channel",
  "id": "reportsApiId",
  "resourceId": "o3hgv1538sdjfh",
  "resourceUri": "https://admin.googleapis.com/admin/reports/v1/activity/userKey/applications/applicationName",
  "token": "target=myApp-myFilesChannelDest",
  "expiration": 3600
}

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

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

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

同步消息

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

您可以放心地忽略 sync 通知,但也可以使用它。例如,如果您决定不再保留该渠道,可以在调用 stop receiving notifications 时使用 X-Goog-Channel-IDX-Goog-Resource-ID 值。您还可以使用 sync 通知进行一些初始化,为后续事件做好准备。

Admin SDK 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。此渠道的每个后续通知的消息编号都比前一个通知的消息编号大,但消息编号不会是连续的。

续订通知渠道

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

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

接收通知

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

解读通知消息格式

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

标头

Admin SDK 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 将此标识为 Activity 资源。值:固定字符串“admin#reports#activity”。
id 活动记录的唯一标识符。
id.time 活动发生的时间。该值采用 ISO 8601 日期和时间格式。时间是完整日期加时、分和秒,格式为 YYYY-MM-DDThh:mm:ssTZD。例如,2010-04-05T17:30:04+01:00。
id.uniqueQualifier 如果多个事件具有相同的时间,则为唯一限定符。
id.applicationName 相应事件所属的应用的名称。可能的值包括:
id.customerId Google Workspace 账号的唯一标识符。
actor 执行操作的用户。
actor.callerType 执行报告中所列活动的作者的类型。在此版本的 API 中,callerType是执行报告中所列操作的USER或 OAuth 2LO 实体请求者。
actor.email 报告中涉及的用户的电子邮件地址。
actor.profileId 用户的唯一 Google Workspace 个人资料 ID。
ownerDomain 管理控制台或 Google 文档应用文档所有者的网域。这是受报告的事件影响的网域。
ipAddress 执行操作的用户的 IP 地址。这是用户登录 Google Workspace 时的互联网协议 (IP) 地址,可能反映用户的实际位置,也可能不反映。例如,IP 地址可以是用户的代理服务器地址或虚拟专用网 (VPN) 地址。该 API 支持 IPv4IPv6
events[] 报告中的活动事件。
events[].type 事件类型。管理员更改的 Google Workspace 服务或功能在 type 属性中标识,该属性使用 eventName 属性标识事件。
events[].name 活动名称。这是 API 报告的活动的具体名称。每个 eventName 都与特定的 Google Workspace 服务或功能相关,API 会将这些服务或功能整理成各种类型的事件。
对于一般 eventName 请求参数:
  • 如果未提供 eventName,报告会返回 eventName 的所有可能实例。
  • 当您请求 eventName 时,API 的响应会返回包含该 eventName 的所有 activity。返回的 activity 可能除了所请求的属性之外,还具有其他 eventName 属性。
events[].parameters[] 各种应用的形参值对。
events[].parameters[].name 参数的名称。
events[].parameters[].value 参数的字符串值。
events[].parameters[].intValue 参数的整数值。
events[].parameters[].boolValue 相应参数的布尔值。

示例

Activity 资源事件的通知消息具有以下一般形式:

POST https://mydomain.com/notifications
Content-Type: application/json; utf-8
Content-Length: 0
X-Goog-Channel-ID: reportsApiId
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/reports/v1/activity/userKey/applications/applicationName
X-Goog-Resource-State:  eventName
X-Goog-Message-Number: 10

{
  "kind": "admin#reports#activity",
  "id": {
    "time": datetime,
    "uniqueQualifier": long,
    "applicationName": string,
    "customerId": string
  },
  "actor": {
    "callerType": string,
    "email": string,
    "profileId": long
  },
  "ownerDomain": string,
  "ipAddress": string,
  "events": [
    {
      "type": string,
      "name": string,
      "parameters": [
        {
          "name": string,
          "value": string,
          "intValue": long,
          "boolValue": boolean
        }
      ]
    }
  ]
}

管理员活动事件示例:

POST https://mydomain.com/notifications
Content-Type: application/json; utf-8
Content-Length: 596
X-Goog-Channel-ID: reportsApiId
X-Goog-Channel-Token: 245t1234tt83trrt333
X-Goog-Channel-Expiration: Tue, 29 Oct 2013 20:32:02 GMT
X-Goog-Resource-ID:  ret987df98743md8g
X-Goog-Resource-URI: https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin?alt=json
X-Goog-Resource-State:  CREATE_USER
X-Goog-Message-Number: 23

{
  "kind": "admin#reports#activity",
  "id": {
    "time": "2013-09-10T18:23:35.808Z",
    "uniqueQualifier": "-0987654321",
    "applicationName": "admin",
    "customerId": "ABCD012345"
  },
  "actor": {
    "callerType": "USER",
    "email": "admin@example.com",
    "profileId": "0123456789987654321"
  },
  "ownerDomain": "apps-reporting.example.com",
  "ipAddress": "192.0.2.0",
  "events": [
    {
      "type": "USER_SETTINGS",
      "name": "CREATE_USER",
      "parameters": [
        {
          "name": "USER_EMAIL",
          "value": "liz@example.com"
        }
      ]
    }
  ]
}

有关通知的操作

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

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

了解 Admin SDK API 通知事件

本部分详细介绍了在使用 Admin SDK API 通过推送通知接收通知消息时,

Reports API 推送通知包含两种类型的消息:同步消息和事件通知。消息类型在 X-Goog-Resource-State HTTP 标头中指明。活动通知的可能值与 activities.list 方法的可能值相同。每个应用都有独特的事件:

停止通知

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

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

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

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

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

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

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

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