【发布时间】:2021-03-25 05:00:42
【问题描述】:
问题的简短描述:
我们的同步设置如下:
通过调用 messages.list 方法在用户的收件箱上执行完全同步。 从响应中保存最高的 historyId 在将通知推送到我们的 webhook 端点后,使用我们之前保存的 startHistoryId 调用 history.list 使用来自响应的 messagesAdded 部分的消息 ID(我们排除 messagesDeleted 部分中的消息和带有 DRAFT 标签的消息),调用 Gmail API 上的 messages.get 方法。 Gmail API 随机返回 404 错误(“未找到请求的实体”)。这通常会突然发生(但并非总是如此),其中 30-50 条据称添加的消息返回 404。我已经验证用户没有设置可能导致它的自动过滤器。它也发生在工作时间之外,这意味着用户无法删除这些消息。 示例:
listHistory 使用 historyId 463077 调用 响应中返回了以下消息:
{
id: '1762a36a2ab4ab29',
threadId: '175e5e4219f86042',
labelIds: [ 'UNREAD', 'IMPORTANT', 'CATEGORY_PERSONAL', 'INBOX' ]
}
getMessage 为该特定消息返回 404(未找到请求的实体)。时间戳 2020-12-03T20:06:42.392Z 一个可靠地重现问题的小代码示例。示例应按原样运行或以最少的设置运行,无需外部依赖。
我们使用的是 googleapis 47.0.0 节点包。
let addedMessageIds: string[] = [];
let deletedMessageIds: string[] = [];
let nextPageToken: undefined | string;
const numbers: number[] = [];
while (true) {
const result = await gmail.users.history.list({
startHistoryId: '664689',
pageToken: nextPageToken,
userId: 'me',
labelId: 'INBOX',
historyTypes: ['MESSAGE_ADDED', 'MESSAGE_DELETED'],
});
for (const historyMessage of result.data.history || []) {
for (const deleted of historyMessage.messagesDeleted || []) {
if (!deleted.message?.id) continue;
deletedMessageIds.push(deleted.message.id);
}
for (const added of historyMessage.messagesAdded || []) {
if (!added.message?.id) continue;
addedMessageIds.push(added.message.id);
}
}
if (!result.data.nextPageToken) break;
nextPageToken = result.data.nextPageToken;
}
for (const id of addedMessageIds) {
if (deletedMessageIds.includes(id)) continue;
try {
await gmail.users.messages.get({
id: id,
userId: 'me',
});
} catch (e) {
console.error('DID NOT GET MESSAGE', {
messageId: id,
error: e.message,
});
}
}
Google Cloud Platform 的指标报告 getMessage 方法的错误率约为 76%。通过比较我们系统中的消息 ID,我们仍然可以获取大部分消息,但不是全部。由于错误率始终在 0 以上,我们无法确定是否收到消息。
为什么我们在使用 getMessage 检索 listHistory 调用返回的消息 ID 时会收到 404 错误?
【问题讨论】:
-
那么您的问题到底是什么? @JeremyDurrance
-
@ale13 使用getMessage获取listHistory调用返回的消息ID为什么会收到404错误的问题?
标签: node.js google-api gmail gmail-api