views:

691

answers:

3

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.

+1  A: 

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
A: 

Thanks for your reply. Now it shows the actual command, but as before there's no notification when a new mail arrives. Do I need to run imap.idle in a for loop or something.

Further, when i issue imap.idle, it return true, but i have to press return twice to get the server response.

?> imap.idle
C: RUBY0005 IDLE
=> true
>>
?>
?> S: + idling
+1  A: 

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