推送通知

概览

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 Developers Console 中为您的项目列出的项目 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 Developer Console 权限界面来实现此目的。

正在获取 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 匹配的邮箱更新时,您的应用都会收到说明相应更改的通知消息。

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

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

然后,您可以按照同步指南使用 history.list 获取用户自上次已知的 historyId 以来的详细更改信息。

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

回复通知

所有通知都需要确认。如果您使用 webhook 推送传送,则成功响应(例如 HTTP 200)将确认通知。

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

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

正在停止邮箱更新

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

限制

通知率上限

所监控的每位 Gmail 用户的通知速率上限为 1 个事件/秒。超过该速率的所有用户通知都将被丢弃。处理通知时要小心,确保不要触发其他通知,从而启动通知循环。

可靠性

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

Cloud Pub/Sub 限制

Cloud Pub/Sub API 也有自己的限制,具体在其pricingquotas文档中对此进行了详细说明。