我设置了一个 webhook,它使用 Google Cloud PubSub API 和 Java 中的 Gmail API 监听和处理 Gmail 中收件箱和发送文件夹中的更改。
我看到的问题是,当我向另一个用户发送消息时,PubSub 似乎两次推送到我的端点一秒钟之内History_id 和 message_id 略有不同,但订阅名称和用户电子邮件相同。
我了解 PubSub 保证至少一次交付因此,收到重复消息并不罕见,但由于这种情况持续发生且 message_id 不同,我认为根据下面的 PubSub 文档,可能存在多个推送请求:
Cloud Pub/Sub 分配一个唯一的message_id
每条消息,可用于检测订阅者收到的重复消息。但是,这不允许您检测对同一数据的多个发布请求所产生的重复项。
我尝试过的:
- 确保我的 Google Cloud 控制台上只有一个主题/订阅。
- 将 Ack 截止时间设置为 10 到 600 秒之间的不同值。
- Called
service.users().stop()
确保我没有打电话watch()
多次然后开始watch()
again.
我研究了 PubSubIO 以确保一次性交付,但我认为如果我持续收到多条 PubSub 消息,那么我设置 webhook 的方式一定存在根本性错误。
编辑:
这是我必须监视 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;
}
我将历史记录和过期时间插入数据库,并使用它来检查,在收到 webhook 调用时,我是否需要调用watch()
如果自上次调用以来已过去超过 24 小时,则再次调用watch
(根据谷歌的推荐)。