Get email information from IMAP (fast)
Email messages include attachments (encoded as text using Base64 or Quoted-Printable encoding). This causes emails to became quite big and download process slow. In many cases you don’t require to download entire message (including attachments) to process it. Think about displaying only a list of messages that are in the INBOX folder or only deciding if you should process a message.
When using IMAP protocol, Mail.dll IMAP client offers extremely fast way of downloading such email information. This include message envelope information (Subject, Date, From and To recipients) and message structure (Attachment count, attachment names and sizes).
In the following sample, we’ll download those data for all unseen messages that are in the INBOX folder:
// C# using (Imap imap = new Imap()) { imap.Connect("imap.example.com"); // or ConnectSSL imap.UseBestLogin("user", "password"); imap.SelectInbox(); List<long> uids = imap.Search(Flag.Unseen); List<MessageInfo> infos = imap.GetMessageInfoByUID(uids); foreach (MessageInfo info in infos) { Console.WriteLine("Subject: " + info.Envelope.Subject); Console.WriteLine("From: " + info.Envelope.From); Console.WriteLine("To: " + info.Envelope.To); foreach (MimeStructure attachment in info.BodyStructure.Attachments) { Console.WriteLine(" Attachment: '{0}' ({1} bytes)", attachment.SafeFileName, attachment.Size); } Console.WriteLine(); } imap.Close(); }
' VB.NET Using imap As New Imap() imap.Connect("imap.example.com") ' or ConnectSSL imap.UseBestLogin("user", "password") imap.SelectInbox() Dim uids As List(Of Long) = imap.Search(Flag.Unseen) Dim infos As List(Of MessageInfo) = imap.GetMessageInfoByUID(uids) For Each info As MessageInfo In infos Console.WriteLine("Subject: " + info.Envelope.Subject) Console.WriteLine("From: " + info.Envelope.From) Console.WriteLine("To: " + info.Envelope.[To]) For Each attachment As MimeStructure In info.BodyStructure.Attachments Console.WriteLine(" Attachment: '{0}' ({1} bytes)", _ attachment.SafeFileName, _ attachment.Size) Next Console.WriteLine() Next imap.Close() End Using
The result of the code above is list of all unread emails with attachments:
Subject: Contract
From: Alice <alice@company.com>
To: Bob <bob@company.com>
Attachment: 'document1.doc' (42738 bytes)
Attachment: '.NET.pdf' (1243 bytes)
Envelope object contains following information:
- Subject
- Date
- From
- Sender
- To
- Cc
- InReplyTo
- Message id
- Message size
- Gmail thread id (if available)
- Gmail message id (if available)
BodyStructure contains information about:
- All attachments including their size, name, content type
- HTML message part
- Pain text message part
It’s really fast. Downloading 1000 email information takes approximately 13 seconds.
You can read more about downloading email parts (single attachment) here
September 17th, 2014 at 16:31
Hi,
Is this any different from the one you did for us? Shall we upgrade to this version for faster download?
September 20th, 2014 at 10:43
@Khash
This feature was introduced in version 3.0.10257.1855.
So if you are using previous version and want to use GetMessageInfo or GetMessageInfoByUID methods you should upgrade.
September 29th, 2014 at 16:30
[…] download emails’ basic information very fast […]
April 7th, 2015 at 08:19
[…] There are two methods for that: GetBodyStructureByUID and GetBodyStructure. You can also use GetMessageInfo and GetMessageInfoByUID methods. Both methods return more information about the email (subject, from, to headers) and […]
April 11th, 2015 at 15:35
Hi,
I tested this code but the Size property returns the mimestructure I have nothing to do with what actually holds the file (eg XLS file size of 59,392 bytes, the property returns me 81274 bytes)
Something wrong?
April 11th, 2015 at 19:33
@Roberto
Can you enable logging, as described here:
http://www.limilabs.com/blog/i-have-problems-issuing-imap-pop3-smtp-command
and we’ll see what the server is sending.
April 12th, 2015 at 10:34
@Roberto
The attachment is Base64 encoded, which typically increase the size of
the attachment by 33%.
Server returns so called ‘transfer size’ (71566 bytes)
Note that this size is the size in attachment’s transfer encoding (Base64) and
not the resulting size after any decoding (‘actual size’).
The problem is that without decoding (which means downloading the
entire attachment) there is no way to know the actual attachment size.
We’ll add better comment on the MimeStructure.Size property.
We’ll also add EstimateActualSize method to MimeStructure that is going to estimate
the ‘actual size’ from the ‘transfer size’ and encoding used.
April 21st, 2015 at 08:51
Hello,
I’d like to use this fast method in my application, but can’t think about a way to retrieve the Priority/Importance this way. I’m sure there is a way, so can you please help me out if you have a little time?
Thanks in advance!
May 6th, 2015 at 18:06
@Boris,
Unfortunately not all headers are included in envelope response.
You can use Imap.GetSpecificHeadersByUID(List uids, string[] headers) to get those you are missing, but expect significant performance drop as this command expects multi-line response.
Please note that this method is available in the newest version of Mail.dll
August 5th, 2015 at 13:45
I noticed that when i use GetSpecificHeadersByUID to recieve headers for specified messages, these messages are being flagged as seen. Please let me know if you plan to fix this. Thanks.
August 6th, 2015 at 10:51
@Jacek
It’s not a bug.
The latest version has PeekSpecificHeaders and PeekSpecificHeadersByUID methods that don’t set Seen flag. Generally Peek* methods in contrast to Get* methods don’t set Seen flag.
October 21st, 2015 at 18:04
[…] download emails’ basic information very fast […]
May 8th, 2016 at 19:36
[…] working with attachments. You can download only parts of email message, which in conjunction with getting basic email information without downloading entire message can make your code very […]
November 22nd, 2016 at 14:42
You say this is the fastest way but when I use: imap.GetHeadersByUID(uids)
I can read 1000 mails in 7-8 seconds, how GetMessageInfo then be the fastest?
November 22nd, 2016 at 15:33
@Math,
GetHeadersByUID downloads only message headers, there are no information about attachments, message size.
You are trying to compare apples to oranges here.
If you don’t care about attachments’ info, GetEnvelopeByUID should be faster then GetHeadersByUID and GetMessageInfoByUID.
August 14th, 2017 at 14:52
Hi, I have followed the example but when trying to output the email from by using info.Envelope.From but instead of getting the actual information I am getting
System.Collections.Generic.List`1[Limilabs.Mail.Headers.MailBox]
Help?!?
August 18th, 2017 at 10:27
@Richard,
Have you used foreach? Envelope.From is a collection.
Each item in this collection is of MailBox type, which has Address and Name properties.