在 Gmail API 中配置推送通知

本文档介绍如何在 Gmail API 中管理推送通知。

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 Cloud 控制台中列出的 项目 ID)。

创建订阅

如需设置对您创建的主题的订阅,请按照 Cloud Pub/Sub 订阅类型 指南操作。 将订阅类型配置为 Webhook 推送(即 HTTP POST 回调)或拉取(即由您的应用发起)。这样,您的应用就可以接收有关更新的通知。

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

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

为此,请向 gmail-api-push@system.gserviceaccount.com 授予 publish 权限。您可以使用 Google Cloud 控制台中的 Cloud Pub/Sub 权限 控制台,按照以下访问权限控制 说明来完成此操作。

您组织的网域限制 共享 配置可能会阻止您授予发布权限。如需解决 此问题,您可以为此服务账号配置 例外情况

获取 Gmail 邮箱更新

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

Watch 请求

如需将 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 响应

如果 watch 请求 成功,您会收到如下所示的响应:

{ historyId: 1234567890 expiration: 1431990098200 }

响应包含用户的当前邮箱 historyId。您的客户端会收到该 historyId 之后的所有更改的通知。如果您需要 处理此 historyId 之前的更改,请参阅将客户端 客户端与 Gmail API 同步

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

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

续订邮箱 Watch

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

接收通知

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

如果您配置了推送订阅,则发送到服务器的 Webhook 通知 将符合 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 字段是 Base64网址 编码的字符串,解码后会得到一个 JSON 对象,其中包含用户的电子邮件地址和新的邮箱历史记录 ID:

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

然后,您可以使用 history.list 方法获取自用户上次已知 historyId以来的更改详情,如将客户端与 Gmail API同步中所述。

例如,使用 history.list 方法来识别在您的初始 watch请求和 收到上一个示例中共享的通知消息之间发生的更改。将 1234567890 作为 startHistoryId 传递给 history.list。之后,您可以将 9876543210 保留为上次已知的 historyId,以供日后使用。

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

有关通知的操作

所有通知都必须确认。如果您使用 Webhook 推送 传送,则成功 响应(例如 HTTP 200)即表示确认通知。

如果您使用拉取传送(REST 拉取RPC 拉取、 或 RPC 流式拉取), 则必须跟进确认调用 (RESTRPC)。如需详细了解如何使用基于官方 RPC 的客户端库以异步同步方式确认消息,请参阅 Cloud Pub/Sub 的拉取 订阅指南中的代码示例。

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

停止邮箱更新

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

限制

使用服务器推送通知存在以下限制:

通知率上限

每个受监视的 Gmail 用户的通知率上限为每秒一个事件。任何超出该速率的用户通知都会被丢弃。 处理通知时,请注意不要触发其他通知,否则可能会启动通知循环。

可靠性

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

Cloud Pub/Sub 限制

Cloud Pub/Sub API 也有自己的限制,这些限制在其 价格配额文档中有详细说明。