jstedfast / MailKit

A cross-platform .NET library for IMAP, POP3, and SMTP.

Home Page:http://www.mimekit.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possible to retrieve message that includes flags, from address, subject, and body content

susnick opened this issue · comments

Forigve me if I am just missing it, but currently I am having to contact server twice to obtain the flags, from address, subject, and body. Can this be done with one retrieval?

var emails = inbox.Fetch(0, -1, MessageSummaryItems.Envelope | 
					         MessageSummaryItems.UniqueId | 
						MessageSummaryItems.Size | 
						MessageSummaryItems.Flags | MessageSummaryItems.Body);

foreach (var item in emails)
{
    var message = inbox.GetMessage(item.UniqueId);
    Console.WriteLine("The message uid: {0}", item.UniqueId);
    Console.WriteLine("The message subject: {0}", item.Envelope.Subject);
    Console.WriteLine("The message is {0} bytes long", item.Size.Value);
    Console.WriteLine("The message has the following flags set: {0}", item.Flags.Value);
    Console.WriteLine("Message is flagged: {0}", message.Importance);
    //inbox.MoveTo(item.UniqueId, procFolder);
}

Here is output. From documentation at http://www.mimekit.net/docs/html/T_MailKit_MessageFlags.htm MessageFlags.Flagged says the message has been flagged for Importance, yet my output when logging mesage.Importance shows Normal.

The message uid: 6
The message subject: testing plus address
The message is 2899 bytes long
The message has the following flags set: Seen, Flagged
Message is flagged: Normal

but currently I am having to contact server twice to obtain the flags, from address, subject, and body. Can this be done with one retrieval?

I don't understand your question. It looks like you are getting all that info in a single request. What am I not understanding about your question?

The following line of code from your snippet does exactly what you are asking how to do:

var emails = inbox.Fetch(0, -1, MessageSummaryItems.Envelope | 
					         MessageSummaryItems.UniqueId | 
						MessageSummaryItems.Size | 
						MessageSummaryItems.Flags | MessageSummaryItems.Body);

That gets you the flags (item.Flags.Value), from address (item.Envelope.From), subject (item.Envelope.Subject) and "body" (item.Body - altho this is really just the body structure which is a tree structure of the MIME "metadata" that provides you with the mime-type and pre-parsed versions of all of the Content-* header values).

If you are asking me how to get the text data for the message body included in the Fetch() request... unfortunately that's not possible because you first need to get the MessageSummary (aka item in your code snippet) so that you can examine the body structure of the message and determine which body part is the "message body" and then use that to get the actual message body content. e.g.:

var plain = (TextPart) inbox.GetBodyPart(item.UniqueId, item.TextBody);
var html = (TextPart) inbox.GetBodyPart(item.UniqueId, item.HtmlBody);

From documentation at http://www.mimekit.net/docs/html/T_MailKit_MessageFlags.htm MessageFlags.Flagged says the message has been flagged for Importance, yet my output when logging mesage.Importance shows Normal.

You are confusing the message's header values with the independent "importance" message flag state that can be set on the message on the server. They are not the same.

When you toggle the "Important" flag in Outlook or in GMail, they do not modify the message headers. They simply set server-side flag on the message. For most IMAP servers, they'll store that flag in a database but it will never be added to the message headers.

Thanks, for the info, I was hoping that MessageSummaryItems.Body would give me the actual body html and text, but it didnt. I am coming from the imapX world, and wanted to change as little of the code as possible.

May I ask the reasoning that MessageSummaryItems are not included with an actual MimeMessage (ie. Size, Flags, UniqueId, etc)?

May I ask the reasoning that MessageSummaryItems are not included with an actual MimeMessage (ie. Size, Flags, UniqueId, etc)?

Because that's not how IMAP works.

MailKit is a lower-level library than ImapX was and is more of a 1:1 mapping of the IMAP protocol.

Secondly, if you are just going to download every message in full anyway, it doesn't make a whole lot of sense to make a Fetch() request for most of the information (other than, I suppose, Flags and Size - but even the Size can be calculated locally by writing the message to a MimeKit.IO.MeasureStream).

Thirdly, if I made it possible to do this:

inbox.Fetch (<range>, MessageSummaryItems.FullMessage | MessageSummaryItems.Flags)

You could end up using gigabytes or even terrabytes of RAM in order to download all of the messages.

The other problem with an approach like that is, even if you as a user of the API understood the memory requirements and were ok with that, there's still the problem of potential exceptions while downloading all of the messages (network connection drops, IMAP server goes down for a restart, etc) which would mean a huge waste of system resources for an operation that didn't complete successfully.

That said, going forward, you may have noticed that starting with 4.x there is now a Fetch() method that takes an IFetchRequest argument and there is a FetchRequest class that implements that interface. What I want to do is to add an optional callback method that would allow you to immediately get each message summary item as they are received rather than having to wait until the request completes before you can process them.

And maybe once I have that in place, maybe it would make sense to allow fetching full messages in a Fetch() request, but I'm not 100% convinced that should be a core feature of the API.

In other words, I'm trying to prevent people from pointing a loaded shotgun at their kneecaps.

That makes sense. I guess I assume people have the same use case as I do. I only ever download a handful of messages. Every message handled gets moved to another folder, or flagged for human intervention.

A handful of messages, in most cases, would probably only use a reasonable amount of memory - but yea, technically, email messages can be up to 4 GB each (which is really only a limitation of IMAP's unsigned 32bit integer syntax).