Thread emails using IMAP

The THREAD extension to the IMAP protocol provide a means of server-based threading of messages, without requiring that the IMAP component download the necessary data to do so itself.

Following sample shows how to use Imap Thread method to thread all emails available in the mailbox.

  • First it checks if THREAD extension is available on the server (defined in RFC 5256).
  • It also downloads envelopes of all email messages to get messages subjects and basic data.
  • Finally recursive ShowThread method is used. It displays message UID and subject in a formatted tree manner.

There is one interesting thing in this sample: you can use any search criterion to get messages from the IMAP server. For example you could only get unseen messages or messages that are unseen and contain a certain word.

// C#

using (Imap imap = new Imap())
{
    imap.Connect("imap.example.org");    // or ConnectSSL
    imap.UseBestLogin("user", "password");
    
    ThreadMethod method = ThreadMethod.ChooseBest(imap.SupportedThreadMethods());
    if (method == null)
        throw new Exception("This server does not support any threading algorithm.");

    imap.SelectInbox();

    List<MessageThread> threads = imap.Thread(method).Where(Expression.All());
    List<Envelope> envelopes = imap.GetEnvelopeByUID(
        imap.Search().Where(Expression.All()));

    foreach (MessageThread thread in threads)
    {
        ShowThread(0, thread, envelopes);
    }
    imap.Close();
}

public void ShowThread(int level, MessageThread thread, List<Envelope> envelopes)
{
    string indent = new string(' ', level*4);
    string subject = envelopes.Find(x => x.UID == thread.UID).Subject;
    Console.WriteLine("{0}{1}: {2}", indent, thread.UID, subject);

    foreach (MessageThread child in thread.Children)
    {
        ShowThread(level + 1, child, envelopes);
    }
}
' VB.NET

Using imap As New Imap()
	imap.UseBestLogin("imap.example.org")	' or ConnectSSL
	imap.Login("user", "password")

	Dim method As ThreadMethod = ThreadMethod.ChooseBest(imap.SupportedThreadMethods())
	If method Is Nothing Then
		Throw New Exception("This server does not support any threading algorithm.")
	End If

	imap.SelectInbox()

	Dim threads As List(Of MessageThread) = _ 
		imap.Thread(method).Where(Expression.All())
	Dim envelopes As List(Of Envelope) = 
		_ imap.GetEnvelopeByUID(imap.Search().Where(Expression.All()))

	For Each thread As MessageThread In threads
		ShowThread(0, thread, envelopes)
	Next
	imap.Close()
End Using

Public Sub ShowThread(level As Integer, thread As MessageThread, envelopes As List(Of Envelope))
	Dim indent As New String(" "C, level * 4)
	Dim subject As String = envelopes.Find(Function(x) x.UID = thread.UID).Subject
	Console.WriteLine("{0}{1}: {2}", indent, thread.UID, subject)

	For Each child As MessageThread In thread.Children
		ShowThread(level + 1, child, envelopes)
	Next
End Sub

Here you can see the results:

2299: First thread
    2300: Re: First thread
    2301: Re: First thread
2302: Second thread
    2303: Re: Second thread
    2304: Re: Re: Second thread
    2305: Re: Re: Re: Second thread

Tags: , , ,

2 Responses to “Thread emails using IMAP”

  1. Atef Ramadan Says:

    Getting error: “This server does not support any threading algorithm”.
    I’m using it with Gmail.

  2. Limilabs support Says:

    @Atef,

    Not all IMAP servers support threading (THREAD extension). In particular Gmail doesn’t. This shows how you can check which extensions your IMAP server supports.

Questions?

Consider using our Q&A forum for asking any questions.