retrieve a single email from imap by message_id
Asked Answered
C

3

6

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?

Chevet answered 1/5, 2014 at 15:48 Comment(1)
Please define "message-id) (do you mean the header? the sequence identifier? the UID?), what code you've tried, what language you're usingPreceptive
F
5

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 <[email protected]>:

0005 UID SEARCH HEADER Message-ID <[email protected]>

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 <[email protected]> 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.

Fan answered 1/5, 2014 at 17:54 Comment(3)
I am using Ruby's Net::IMAP objectChevet
Like I said, you have to use IMAP search functionality. Ruby's Net::IMAP has such functionality - see ruby-doc.org/stdlib-2.1.0/libdoc/net/imap/rdoc/Net/IMAP.html for an example. Just adapt it to the commands I provided above.Fan
And use BODY.PEEK instead of just BODY to prevent marking the message as read (\Seen) by accident.Tighe
C
1

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

keys: ['HEADER', 'MESSAGE-ID', message_id]
Chevet answered 18/6, 2014 at 10:56 Comment(0)
D
1

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
Deduct answered 27/10, 2016 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.