【发布时间】:2019-11-07 13:26:21
【问题描述】:
我正在尝试使用 Gmail api 来同步用户 Gmail 收件箱中的所有电子邮件。我正在使用 Gmail 的“同步客户端”[1] 文档中描述的部分同步技术。列出的限制之一是,在极少数情况下,某些电子邮件的 historyId 不可用。在这种情况下,建议客户端重新使用“完全同步”,即客户端应“检索并存储尽可能多的最新消息或线程,以达到您的目的”。
这一切都说得通。当我遇到部分同步问题时,我会尝试按时间范围查看收件箱消息。为此,我有效地存储了我同步的每封电子邮件的( emailAddress, historyId, internalDate ) 的记录,然后当退回到完全同步时,我尝试同步自我已经同步的最新internalDate 以来的所有电子邮件。
我的问题是,似乎导致部分同步失败的案例似乎也导致了完全同步失败,其中许多案例是由internalDates的电子邮件引起的将来(出于隐私原因,我无法分享这些示例)。失败案例好像是这样的
- 我将电子邮件 E 与 historyId H 和一个 internalDate I 同步
- 一段时间过去了
- 我收到来自 google 的推送通知,表明他们是要同步的新电子邮件
- 我查找我为此收件箱 ID 同步的最新消息,找到电子邮件 E
- 我尝试使用 listHistory [2] 端点和 historyId H 进行部分同步
- listHistory 请求失败并返回 404
- 我尝试使用查询
newer_than:{hours_since-internalDate-I}使用 listMessages [3] 端点进行完全同步,但此请求没有任何意义,因为此消息的internalDate是将来的。
我可以想象一些不同的解决方案来解决这个问题。也许我应该简单地将这些电子邮件视为垃圾邮件,或者我应该存储我同步每封电子邮件的时间戳,然后对我存储的时间戳执行完全同步。
不管怎样,这似乎是 Gmail API 中的一个错误,因为internalDate 应该是 Gmail 收到电子邮件时的真实值。我最初怀疑这可能是由 Gmail 的新日程安排功能引起的,internalDate 可能是将来安排电子邮件的时间,但我确认我的一些示例肯定是针对用户收件箱 收到,而不是发送。真的不知道在internalDate api 中如何处理这个边缘案例。
所以我的问题是,处理虚假未来internalDates 的建议方法是什么?这是一个错误吗?
【问题讨论】:
-
你发送
{hours_since-internalDate-I}参数的格式是什么?internalDate由Users.messages: list在 Unix 时间中以毫秒为单位返回。 internalDate 的未来有多远?每次查询 internalDate 时都会发生这种情况,还是偶尔会发生? -
嘿@RafaGuillermo,很抱歉对此反应缓慢。您的问题的答案... 1. 我们将
internalDate格式化为一个小时。又名newer_than:1h。然而,使用纪元秒似乎是一个更精确的解决方案,我注意到使用after:epoch_second的 api 支持这一点。 2. 以我的未来邮件为例,internalDate 为 2085776896000,即 2036 年。这是一封带有 INBOX 标签的邮件,所以我说它不是预定邮件。 -
嘿,我想我找到了一个可行的解决方案。诀窍是添加一个防御性
before:epochSecondOfCurrentTime搜索参数。这可以防止 Gmail 返回带有未来内部日期的电子邮件。似乎仍然存在内部日期为 2036 年的电子邮件是一个错误,但通过简单的解决方法对我来说并没有那么紧迫。 -
感谢您回复我,您是否曾将邮件从其他客户端迁移到 GMail 或通过 API 插入邮件?默认情况下,当邮件被迁移/插入时,或者在使用 IMAP 时,GMail 将查看邮件的标题,然后在查询中使用“dateHeader”作为
internalDateSource参数的值,如果它们不会清理日期'是畸形的,来自未来。 -
internalDateSource是Users.messages: insert请求的可选查询参数,可让您告诉 GMail 从何处获取插入邮箱的电子邮件消息的日期。 'dateHeader' 是internalDateSource的字符串值,这就是告诉GMail 查看邮件的日期标题的原因。如果这些标题被破坏并说它们在未来,那么 GMail 也会这样读取它们。
标签: gmail-api