9

Ok, I have been suck on it for hours. I thought net/imap.rb with ruby 1.9 supported the idle command, but not yet.

Can anyone help me in implementing that? From here, I though this would work:

class Net::IMAP
  def idle
    cmd = "IDLE"
    synchronize do
      tag = generate_tag
      put_string(tag + " " + cmd)
      put_string(CRLF)
    end
  end

  def done
    cmd = "DONE"
    synchronize do
      put_string(cmd)
      put_string(CRLF)
    end
  end
end

But imap.idle with that just return nil.

4 Answers4

8

I came across this old question and wanted to solve it myself. The original asker has disappeared - oh well.

Here's how you get IMAP idle working on Ruby (this is super cool). This uses the quoted block in the original question, and the documentation here.

imap = Net::IMAP.new SERVER, :ssl => true
imap.login USERNAME, PW
imap.select 'INBOX'

imap.add_response_handler do |resp|
  # modify this to do something more interesting.
  # called every time a response arrives from the server.
  if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
    puts "Mailbox now has #{resp.data} messages"
  end
end

imap.idle  # necessary to tell the server to start forwarding requests.
Peter
  • 127,331
  • 53
  • 180
  • 211
  • does this renew the imap connection before it expires (supposedly after 30 minutes)? – ckarbass Mar 07 '11 at 06:42
  • 1
    @ckarbass: no, it doesn't. have a look at my complete code example here: http://paste.ly/5wrj. – Peter Mar 08 '11 at 00:29
  • 1
    @Peter I'm sorry, but your paste.ly link is down. Would you mind resubmitting your sample to another service like http://gist.github.com? I'd love to see the example, as I am interested in the exact same question. – Overbryd Nov 20 '11 at 21:13
  • 1
    @Overbryd not sure if this is 1000 years too late, but: https://gist.github.com/2783772 – Peter May 24 '12 at 19:40
  • Hey, this is awesome! @Peter do you have any insight into how this solution scales with multiple users? – Andrew Zimmer Sep 27 '12 at 16:35
  • @Andrew - unfortunately I don't know any scaling details. check back in once you do though! :) – Peter Oct 02 '12 at 18:27
  • @Peter - I posted as an answer below so I wouldn't clog this comment thread. – Andrew Zimmer Oct 03 '12 at 15:36
  • reading ruby 2.1 documentation, I think the answer here is outdated or wrong; see my answer below – Giorgio Robino Dec 13 '14 at 16:18
1

Are you sure it isn't working? Have you looked at the strings it has sent over the socket?

After doing some digging, it looks like put_string returns nil unless you have debug enabled, which is why imap.idle returns nil.

So your idle method might very well be working since it isn't throwing errors.

Does that help explain the behavior?

If you want to use debug, use Net::IMAP.debug = true

BaroqueBobcat
  • 10,090
  • 1
  • 31
  • 37
0

@Peter

I've done some research on how to scale an IDLE IMAP solution. I'm now essentially thinking of 2 options.

Option 1: Run a daemon that checks the mail for all accounts on a continuous loop.

Option 2: Open an IDLE connection for every account and receive updates.

Since my app is dealing with multiple (perhaps thousands or hundreds of thousands of accounts) option 2 seems like an impossibility. I think my best bet is to go with option one, and then break the server into multiple workers after hitting some sort of maximum.

The basic code/idea is outlined here http://railspikes.com/2007/6/1/rails-email-processing

Andrew Zimmer
  • 3,183
  • 1
  • 19
  • 18
  • 1
    I've been working on getting IDLE working with Gmail on a Rails app for a while now, I'm doing something quite similar to: https://gist.github.com/jem/2783772 -- However, it causes all sorts of issues when workers restart, etc. Things start to get pretty hectic with all the threads. Since your answer, have you had any luck with getting IDLE to work with lots of users? Any tips, tricks or suggestions? – Domness Jul 05 '13 at 23:02
0

with Ruby 2.x: the solution is described by mzolin's code chunk here: https://stackoverflow.com/a/21345164/1786393

I just wrote a complete (but still draft) script to fetch unseen mails here https://gist.github.com/solyaris/b993283667f15effa579

btw, comments welcome.

Community
  • 1
  • 1
Giorgio Robino
  • 2,148
  • 6
  • 38
  • 59