自上次检查以来的 Ruby IMAP "changes"

标签 ruby ruby-on-rails-3 imap uid

我正在使用 Ruby 和 Rails 开发 IMAP 客户端。我可以成功导入消息、邮箱等...但是,在初始导入后,我如何检测自上次同步以来发生的任何更改?

目前我正在将 UID 和 UID 有效性值存储在数据库中,比较它们并进行适当的搜索。这有效,但它不会检测到已删除的消息或消息标志的更改等。

我是否必须每次都拉取所有消息来检测这些变化?其他 IMAP 客户端如何快速完成此操作(即 Apple Mail 和 Postbox)。我的脚本已经为每个帐户花费了 10 秒以上的时间,电子邮件地址很少:

# select ourself as the current mailbox
@imap_connection.examine(self.location)

# grab all new messages and update them in the database
# if the uid's are still valid, we will just fetch the newest UIDs
# otherwise, we need to search when we last synced, which is slower :(
if self.uid_validity.nil? || uid_validity == self.uid_validity
  # for some IMAP servers, if a mailbox is empty, a uid_fetch will fail, so then
  begin
    messages = @imap_connection.uid_fetch(uid_range, ['UID', 'RFC822', 'FLAGS'])
  rescue
    # gmail cries if the folder is empty
    uids = @imap_connection.uid_search(['ALL'])
    messages = @imap_connection.uid_fetch(uids, ['UID', 'RFC822', 'FLAGS']) unless uids.empty?
  end

  messages.each do |imap_message|
    Message.create_from_imap!(imap_message, self.id)
  end unless messages.nil?
else
  query = self.last_synced.nil? ? ['All'] : ['SINCE', Net::IMAP.format_datetime(self.last_synced)]
  @imap_connection.search(query).each do |message_id|
    imap_message = @imap_connection.fetch(message_id, ['RFC822', 'FLAGS', 'UID'])[0]

    # don't mark the messages as read
    #@imap_connection.store(message_id, '-FLAGS', [:Seen])

    Message.create_from_imap!(imap_message, self.id)
  end
end

# now assume all UIDs are valid
self.uid_validity = uid_validity

# now remember that we just fetched all those messages
self.last_synced = Time.now
self.save!

最佳答案

Quick Flag Changes Resynchronization 有一个 IMAP 扩展 (RFC-4551)。使用此扩展,可以搜索自上次同步以来已更改的所有消息(基于某种时间戳)。但是,据我所知,此扩展并未得到广泛支持。

有一个信息性 RFC 描述了 IMAP 客户端应该如何进行同步(RFC-4549,第 4.3 节)。文中推荐发出以下两条命令:

tag1 UID FETCH <lastseenuid+1>:* <descriptors>
tag2 UID FETCH 1:<lastseenuid> FLAGS

第一个命令用于获取所有未知邮件所需的信息(不知道有多少邮件)。第二个命令用于同步已查看邮件的标志。

据我所知,这种方法被广泛使用。因此,许多 IMAP 服务器包含优化以快速提供此信息。通常,网络带宽是限制因素。

关于自上次检查以来的 Ruby IMAP "changes",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10076690/

相关文章:

ruby-on-rails - Rails 3 可评级模型 - 如何创建 ajax 评级?

ruby-on-rails - 销毁路径在 Ruby on Rails 中不起作用

PHP imap_open() => [AUTHENTICATIONFAILED] for imap.gmail.com

sql - ActiveRecord::Relation join,如何将连接表的一列添加到新名称的查询结果中?

java - Blackberry 中的独立邮件 API

android - 如何在 Android 中用户请求时在电子邮件中添加服务器端过滤器/规则?

ruby - 如何 "unflatten"一个 Ruby 数组?

Ruby : Fiber yield and fiber. 恢复参数 -

ruby - '**/*.coffee' 是什么意思?

ruby-on-rails - 什么时候应该在 Ruby 中使用表达式插值?