Google PubSub / Gmail Webhook:发送电子邮件时始终从 PubSub 接收多个 POST 请求

Posted

技术标签:

【中文标题】Google PubSub / Gmail Webhook:发送电子邮件时始终从 PubSub 接收多个 POST 请求【英文标题】:Google PubSub / Gmail Webhook: Consistently Receiving Multiple POST Requests From PubSub When Sending An Email 【发布时间】:2019-05-06 06:23:52 【问题描述】:

我设置了一个 webhook,它使用 Google Cloud PubSub API 和 Java 中的 Gmail API 监听和处理 Gmail 中我的 INBOX 和 SENT 文件夹中的更改。

我看到的问题是,当我向另一个用户发送消息时,PubSub 似乎 在一秒钟内两次推送到我的端点,history_id 和 message_id 略有不同,但订阅相同名称和用户电子邮件。

我了解 PubSub 保证至少一次交付,因此收到重复的消息并不少见,但因为它一直在发生并且 message_id 不同,我想可能会有基于以下 PubSub 文档的多个推送请求:

Cloud Pub/Sub 为每条消息分配一个唯一的message_id,可用于检测订阅者收到的重复消息。但是,这将不允许您检测因对同一数据的多个发布请求而产生的重复。

我尝试过的:

    确保我的 Google Cloud 控制台上只有一个主题/订阅。 在 10 到 600 秒之间设置不同的 Ack 截止时间值。 致电service.users().stop() 以确保我没有多次致电watch(),然后再次开始watch()

我研究了 PubSubIO 以确保完全一次交付,但我认为如果我一直收到多条 PubSub 消息,那么我的设置方式肯定存在根本问题我的网络钩子。

编辑: 这是我必须观察我的 Gmail 帐户更改的代码。我正在使用具有域范围权限的服务帐户来访问整个域中的帐户

public static Map<String, String> watchInbox(Gmail service) throws IOException 
    Map<String, String> watchInboxResponse = new HashMap<>();
    List<String> labelsToWatch = Arrays.asList("INBOX", "SENT");
    String topicName = "projects/subscription-name/topics/topic-name";

    WatchRequest request = new WatchRequest();
    request.setLabelIds(labelsToWatch);
    request.setTopicName(topicName);

    WatchResponse response = service.users().watch("me", request).execute();

    watchInboxResponse.put("historyId", response.getHistoryId().toString());
    watchInboxResponse.put("expiration", response.getExpiration().toString());
    return watchInboxResponse;

我将 historyid 和过期时间插入数据库并使用它来检查,在收到 webhook 调用后,如果自上次调用 watch 以来已经过去了超过 24 小时,我是否需要再次调用 watch()(建议由谷歌)。

【问题讨论】:

您可以添加任何详细信息,例如:使用的代码,遇到的错误问题吗? How do I ask a good question?, How to create a Minimal, Complete, and Verifiable example 向社区展示你的尝试。 请增强您的代码。您所包含的示例非常少,对解决方案没有帮助。 您找到解决方案了吗?我也有类似的问题:***.com/questions/53619495/… 【参考方案1】:

我在实现 Google 发布/订阅观看请求时也有类似的行为。

Gmail 在您撰写邮件时所做的是创建系统标签 “发送和草稿” 并不断使用新的 messageId 和标签“发送和草稿”保存到草稿,您订阅了“收件箱和发送”的任何更改,因此您的 webhook 将被点击两次或更长时间!

来自 Gmail 的邮件始终包含标签,您必须过滤具有标签草稿的邮件。

我的代码使用 Gmail .net SDK 并且必须处理

//Explicitly avoid further processing
 bool isdraft = y.Message.LabelIds.Contains("DRAFT");

并过滤那些不管。

【讨论】:

以上是关于Google PubSub / Gmail Webhook:发送电子邮件时始终从 PubSub 接收多个 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

使用 Google Cloud PubSub 不断收到“向 Cloud PubSub 发送测试消息时出错...”

基于特定电子邮件 ID 的 Google Pubsub 订阅

gmail.users.watch 无法使用 DwD 服务帐户向 PubSub 发送测试消息

setIamPolicy 的 Gmail 通知问题

是否可以添加一个包含端口的 pushEndpoint?

如何使用当前的 pubsub 订阅者从 google Pub/Sub 系统获取消息