本文档介绍了如何在 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 账号以发送有关邮箱更新的通知。
观看请求
如需将 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 之前处理更改,请参阅使用 Gmail API 同步客户端。
此外,成功的 watch 调用会导致系统立即向您的 Cloud Pub/Sub 主题发送通知。
如果您收到来自 watch 调用的错误,详细信息应说明问题的来源。这通常是 Cloud Pub/Sub 主题和订阅设置方面的问题。请参阅 Cloud Pub/Sub 文档,确认设置是否正确,并获取有关调试主题和订阅问题的帮助。
续订邮箱监控
您必须每 7 天至少调用一次 watch,否则您将无法再接收用户的更新。我们建议每天调用 watch 一次。watch 方法响应还包含一个 expiration 字段,其中包含 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 字段是一个 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 Pull、RPC Pull 或 RPC StreamingPull),则必须跟进确认调用(REST 或 RPC)。如需详细了解如何使用基于官方 RPC 的客户端库异步或同步确认消息,请参阅 Cloud Pub/Sub 的拉取订阅指南中的代码示例。
如果您未确认通知(例如,如果您的 Webhook 回调返回错误或超时),Cloud Pub/Sub 会在稍后重试通知。
停止接收邮箱更新
如需停止接收邮箱更新,请调用 stop 方法。所有新通知都应在几分钟内停止。
限制
使用服务器推送通知时存在以下限制:
通知速率上限
每个受监控的 Gmail 用户的通知速率上限为每秒一个事件。任何超出该速率的用户通知都会被舍弃。 处理通知时,请注意不要触发另一个通知,否则可能会启动通知循环。
可靠性
通常情况下,所有通知都会在几秒钟内可靠地送达;不过,在某些极端情况下,通知可能会延迟或丢失。妥善处理此可能性,以便即使未收到推送消息,应用仍能同步。例如,在一段时间内没有收到用户通知后,回退到定期调用 history.list 方法。
Cloud Pub/Sub 限制
Cloud Pub/Sub API 也有自己的限制,详细信息请参阅其价格和配额文档。