推送通知

概览

Gmail API 提供服务器推送通知,可让您监视 Gmail 邮箱更改。您可以使用此功能来提升应用的性能。这样,您就可以消除轮询资源以确定其是否发生更改所涉及的额外网络和计算开销。每当邮箱发生变化时,Gmail API 都会通知您的后端服务器应用。

初始 Cloud Pub/Sub 设置

Gmail API 使用 Cloud Pub/Sub API 来传送推送通知。这样,您就可以通过多种方法(包括在单个订阅端点上使用 webhook 和轮询)接收通知。

前提条件

如需完成此设置的其余部分,请确保您满足 Cloud Pub/Sub 前提条件,然后设置 Cloud Pub/Sub 客户端

创建主题

使用 Cloud Pub/Sub 客户端创建一个主题,Gmail API 应将通知发送到该主题。主题名称可以是您在项目下选择的任何名称(即与 projects/myproject/topics/* 匹配,其中 myproject 是 Google 开发者控制台中为您的项目列出的项目 ID)。

由于 Cloud Pub/Sub 对主题数量有限制,因此我们建议您为应用的所有 Gmail API 推送通知使用单个主题。

创建订阅

按照 Cloud Pub/Sub 订阅者指南设置对您创建的主题的订阅。将订阅类型配置为 Webhook 推送(即 HTTP POST 回调)或拉取(即由您的应用发起)。您的应用将通过此方式接收更新通知。

针对您的主题授予发布权限

Cloud Pub/Sub 要求您向 Gmail 授予向您的主题发布通知的权限。

为此,您需要向 gmail-api-push@system.gserviceaccount.com 授予 publish 权限。您可以按照资源级访问控制说明,使用 Cloud Pub/Sub 开发者控制台权限界面执行此操作。

接收 Gmail 邮箱更新

完成初始 Cloud Pub/Sub 设置后,请配置 Gmail 账号以发送邮箱更新通知。

观看请求

如需将 Gmail 账号配置为向您的 Cloud Pub/Sub 主题发送通知,只需使用 Gmail API 客户端对 Gmail 用户邮箱调用 watch,就像调用任何其他 Gmail API 一样。为此,请在 watch 请求中提供上述创建的主题名称以及任何其他选项,例如要用于过滤的 labels。例如,若要每当收件箱发生更改时收到通知,请执行以下操作:

协议

POST "https://www.googleapis.com/gmail/v1/users/me/watch"
Content-type: application/json

{
  topicName: "projects/myproject/topics/mytopic",
  labelIds: ["INBOX"],
  labelFilterBehavior: "INCLUDE",
}

Python

request = {
  'labelIds': ['INBOX'],
  'topicName': 'projects/myproject/topics/mytopic',
  'labelFilterBehavior': 'INCLUDE'
}
gmail.users().watch(userId='me', body=request).execute()

观看回复

如果 watch 请求成功,您将收到如下响应:

{
  historyId: 1234567890
  expiration: 1431990098200
}

使用用户的当前邮箱 historyId。系统会将 historyId 之后的所有更改通知给您的客户。如果您需要处理在此 historyId 之前发生的更改,请参阅同步指南

此外,成功调用 watch 应会导致系统立即向您的 Cloud Pub/Sub 主题发送通知。

如果您收到 watch 调用的错误,详细信息应能说明问题的来源,通常是 Cloud Pub/Sub 主题和订阅的设置。请参阅 Cloud Pub/Sub 文档,确认设置是否正确,并获取有关调试主题和订阅问题的帮助。

续订邮箱监控

您必须至少每 7 天重新调用 watch 一次,否则将停止收到用户的更新。我们建议每天调用一次 watchwatch 响应还包含一个包含 watch 到期时间戳的到期字段。

接收通知

每当发生与您的 watch 匹配的收件箱更新时,您的应用都会收到一条描述更改的通知消息。

如果您已配置推送订阅,则发送到服务器的网络钩子通知将符合 PubsubMessage

POST https://yourserver.example.com/yourUrl
Content-type: application/json

{
  message:
  {
    // This is the actual notification data, as base64url-encoded JSON.
    data: "eyJlbWFpbEFkZHJlc3MiOiAidXNlckBleGFtcGxlLmNvbSIsICJoaXN0b3J5SWQiOiAiMTIzNDU2Nzg5MCJ9",

    // This is a Cloud Pub/Sub message id, unrelated to Gmail messages.
    "messageId": "2070443601311540",

    // This is the publish time of the message.
    "publishTime": "2021-02-26T19:13:55.749Z",
  }

  subscription: "projects/myproject/subscriptions/mysubscription"
}

HTTP POST 正文为 JSON,实际的 Gmail 通知载荷位于 message.data 字段中。该 message.data 字段是 base64url 编码的字符串,解码后会生成一个 JSON 对象,其中包含用户的电子邮件地址和新的邮箱历史记录 ID:

{"emailAddress": "user@example.com", "historyId": "9876543210"}

然后,您可以使用 history.list 获取自用户的上次已知 historyId 以来的更改详情,如同步指南所述。

如果您改为配置了拉取订阅,请参阅 Cloud Pub/Sub 订阅方拉取指南中的代码示例,详细了解如何接收消息。

回复通知

所有通知都需要确认。如果您使用网络钩子推送传送,则成功响应(例如 HTTP 200)即表示确认通知。

如果使用拉取提交(REST 拉取RPC 拉取RPC StreamingPull),则必须进行确认调用(RESTRPC)。如需详细了解如何使用基于 RPC 的官方客户端库异步同步确认消息,请参阅 Cloud Pub/Sub 订阅者拉取指南中的代码示例。

如果未确认通知(例如,您的 Webhook 回调返回错误或超时),Cloud Pub/Sub 会稍后重试通知。

停止邮箱更新

如需停止接收邮箱的更新,请调用 stop,所有新通知应该会在几分钟内停止。

限制

通知速率上限

每个被监控的 Gmail 用户的通知速率上限为 1 事件/秒。如果用户的通知速率超过此上限,系统会丢弃所有超出此速率的用户通知。处理通知时请务必小心,确保不会触发其他通知,从而启动通知循环。

可靠性

通常,所有通知都应在几秒钟内可靠地传送;但在某些极端情况下,通知可能会延迟或丢失。请务必妥善处理这种可能性,以便即使未收到任何推送消息,应用也能正常同步。例如,在用户在一段时间内未收到任何通知后,改为定期调用 history.list

Cloud Pub/Sub 限制

Cloud Pub/Sub API 也有自己的限制,具体详见其价格配额文档。