20

我正在编写一个客户端应用程序,它从 IMAP 服务器获取电子邮件,然后将它们存储在数据库中。问题是,一旦我检查了邮件,下次我只想下载从那以后到达的邮件。因此,如果我在两小时前检查了服务器的邮件,我只想获取最近两小时内到达的邮件。

我可以将 SEARCH 与 SINCE DATE 一起使用,但不支持时间 + 日期很容易被欺骗。

我也尝试了 RECENT 标志,但这似乎不适用于 gmail(在 ruby​​ 中它每次都显示 nil)。

4

3 回答 3

41

您希望对消息使用 UniqueId (UID)。这就是创建它的具体原因。

您需要跟踪最后一次请求的 UID,然后,要请求所有新消息,请使用消息集“[UID]:*”,其中 [UID] 是实际的 UID 值。

例如,假设获取的最后一条消息的唯一 ID 为“123456”。你会取

123456:*

然后,丢弃第一个返回的消息。

UID 被“假定”在会话中是稳定的,并且永远不会改变,并且总是会增加价值。验证这一点的关键是在您选择文件夹时检查 UIDValidity。如果 UIDValidity 数字没有改变,那么 UID 应该在会话中仍然有效。

以下是 RFC 中的相关部分:

2.3.1.1。唯一标识符 (UID) 消息属性

分配给每条消息的 32 位值,当与唯一标识符有效性值(见下文)一起使用时,形成一个 64 位值,该值不得永远引用邮箱中的任何其他消息或任何具有相同名称的后续邮箱。唯一标识符在邮箱中以严格的升序方式分配;当每条消息被添加到邮箱时,它被分配一个比之前添加的消息更高的 UID。与消息序列号不同,唯一标识符不一定是连续的。

消息的唯一标识符在会话期间不得更改,并且不应在会话之间更改。会话之间唯一标识符的任何更改都必须使用下面讨论的 UIDVALIDITY 机制来检测。客户端需要持久的唯一标识符才能从与服务器的先前会话中重新同步其状态(例如,断开连接或离线访问客户端);这将在 [IMAP-DISC] 中进一步讨论。

注意:下一个唯一标识符值旨在为客户端提供一种方法来确定自上次检查此值以来是否有任何消息已传递到邮箱。

这是包含更多信息的链接:

http://www.faqs.org/rfcs/rfc3501.html

我会做的,也是跟踪下载的消息的 InternalDate。这样,如果您丢失了 UID 同步,您至少可以遍历消息,并根据消息的 InternalDate 找到您下载的最后一个。

于 2009-07-06T13:03:26.823 回答
4

有一个名为“seen”的 imap 标志。大多数客户端会在查看消息时标记看到消息,因此您希望遍历服务器上没有设置该标志的消息。

这是一个代码片段,它应该给你正确的想法。操作位当然是

imap.search(["NOT", "SEEN"]).each do bla.bla.bla
于 2009-07-05T21:07:59.320 回答
0

如果您能够将传入的邮件过滤到服务器端的特定 IMAP 文件夹中,您的应用程序可以读取该文件夹中的新邮件,然后在完成后将它们移动到标准收件箱文件夹中。

于 2009-07-05T23:03:44.157 回答