retrieve a single email from imap by message_id

2019-04-02 02:26发布

问题:

I am using ruby's Net::IMAP object and I can retrieve a set of emails using either:

IMAP.all ..args..

Or

IMAP.find ..args..

But is there anyway of retrieving a specific email, preferably by the message-id header for example?

Is this possible or am I limited to all and find and trying to narrow the result set with better arguments?

回答1:

I didn't understand what technology you're using with IMAP. However the IMAP Specification provides the ability to search by a variety of fields, including email headers. You can use the following IMAP command to retrieve the UID of an email with Message-Id <53513DD7.8090606@imap.local>:

0005 UID SEARCH HEADER Message-ID <53513DD7.8090606@imap.local>

This will then give you a response such as the following:

* SEARCH 1
0005 OK UID completed

In my case the email with Message-Id <53513DD7.8090606@imap.local> was the first one, so the SEARCH command returned a matching UID of 1.

You can then retrieve the message using a UID FETCH command, such as the following:

0006 UID FETCH 1 BODY[]

Naturally, if you know the UID in advance, you can skip the UID SEARCH step, but that depends on your application.



回答2:

For anybody else who is looking at this, these keys will do the trick:

keys: ['HEADER', 'MESSAGE-ID', message_id]


回答3:

Just to give a full ruby solution incase it's helpful to someone else.

Bear in mind that if the message is in a subfolder you'll need to manually search through each folder to find the message you are after.

search_message_id = "<message-id-you-want-to-search-for>"

email = "youremail-or-imap-login"
password = "yourpassword"

imap = Net::IMAP.new("imap.example.com", 993, ssl: true)
imap.login(email, password)

imap.select("Inbox")
imap.search(["HEADER", "Message-ID", search_message_id]).each do |message_id|
  envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
  puts "Id:\t#{envelope.message_id}"
  puts "From:\t#{envelope.from[0].mailbox}@#{envelope.from[0].host}"
  puts "To:\t#{envelope.to[0].mailbox}@#{envelope.to[0].host}"
  puts "Subject:\t#{envelope.subject}"
end

imap.logout
imap.disconnect

You can change the above to search all sub-folders by doing:

folders = imap.list("", "*")
folders.each do |folder|
  imap.select(folder.name)
  imap.search # ...
end


标签: email imap