Access custom email header using IMAP

Most common email headers like From, Subject, Date, To, Cc etc. are exposed by IMail interface as properties. Those properties contain parsed information and return strong typed objects like DateTime‘s, string collections, MailAddress collections.

There are times however that you need to access non-standard email header. Good example is a need to get a spam value that your IMAP server assigns to every email by inserting additional ‘x-spam’ header.

Mail.dll MIME and S/MIME parser allows users to access entire MIME tree of the message. IMail.Document property returns MIME document that represent this email message. You can use IMail.Document.Root.Headers collection to access any non-standard and standard header.

If you are using IMAP client you can also search IMAP server for messages that have specified header or have specified value in header.

If you only need to access email headers, consider using GetHeadersByUID method, which doesn’t download entire message from IMAP server just headers. The sample below on the other hand downloads entire message.

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Client.IMAP;

class Program
{
    static void Main(string[] args)
    {
        using (Imap imap = new Imap())
        {
            imap.Connect("imap.example.com");    // or ConnectSSL for SSL
            imap.Login("user", "password");

            MailBuilder builder = new MailBuilder();
            foreach (long uid in imap.GetAll())
            {
                var eml = imap.GetMessageByUID(uid);
                IMail email = builder.CreateFromEml(eml);
                Console.WriteLine("subject: {0}", email.Subject);

                // Get custom header:
                string header = email.Document.Root.Headers["x-spam"];
                Console.WriteLine("x-spam: {0}", header);
            }
            imap.Close();
        }
    }
};
' VB.NET version

Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.IMAP

Public Module Module1
    Public Sub Main(ByVal args As String())

        Using imap As New Imap()
            imap.Connect("imap.example.com")    ' or ConnectSSL for SSL
            imap.Login("user", "password")

            Dim builder As New MailBuilder()
            For Each uid As String In imap.GetAll()
                Dim eml = imap.GetMessageByUID(uid)
                Dim email As IMail = builder.CreateFromEml(eml)
                Console.WriteLine("subject: {0}", email.Subject)

                ' Get custom header:
                Dim header As String = email.Document.Root.Headers("x-spam")
                Console.WriteLine("x-spam: {0}", header)
            Next
            imap.Close()
        End Using

    End Sub
End Module

Tags:    

Questions?

Consider using our Q&A forum for asking questions.

9 Responses to “Access custom email header using IMAP”

  1. Paul Says:

    Is the Headers collection case sensitive? In other words, if the header I’m looking for is “Delivered-To” and I use “delivered-to” as the index, will it work? If not, is there a fast way of specifying case insensitivity?

  2. Limilabs support Says:

    @Paul,

    Headers collection is not case sensitive.
    This means that email.Document.Root.Headers[“Delivered-To”] and email.Document.Root.Headers[“delivered-to”] return same header value.

  3. Paul Says:

    Thanks. One more question. I noticed that there is more than one Delivered-To header but the Headers collection only returns one string value. How do I find them all and loop through? I want the one at the top (the one that Gmail stamps on with the inbox address) but I don’t know if that’s the one that will be returned.

  4. Paul Says:

    I did some testing and it appears that it returns the top-most header if there is more than one. That’s good for me, but it may cause problems for other developers.

  5. Limilabs support Says:

    @Paul

    You are correct. In most cases there is just a single instance of particular email header.
    You can use GetValues method to access multiple headers:

    List<string> values = mail.Headers.GetValues("Received");
    
  6. Math Says:

    Is it possible that there is a limit on how many uids you can give with: imap.GetHeadersByUID(uids)?

  7. Limilabs support Says:

    @Math

    Neither IMAP protocol nor Mail.dll has such limit.
    As for the servers, some, like Gmail, limit certain operations, but it happens rather on search level and usually is configurable.

  8. Fred Says:

    I see some custom header in a attachmail via Outlook/Tags/Header but not more with your interface…

    This code remove Non standard Header? :

    byte[] eml = email.Attachments[1].Data;
    IMail attachedMessage = new MailBuilder().CreateFromEml(eml);

  9. Limilabs support Says:

    @Fred,

    Mail.dll does not remove custom headers. All email headers are available using IMail.Headers collection. Are you sure this header is there (examine the text of this attachment)? Please contact us directly if you believe this is a parser problem.

    Additionally you can make your code a bit more readable:

    MimeRfc822 rfc822 = (MimeRfc822) mail.Attachments[1];
    IMail attached = rfc822.Message;