Search code examples
c#.netemailsmtpmailkit

MailKit Reply Email Not Threading Correctly with Original Message


When I answer the first (i.e. oldest) email in a thread of mails (between two gmail accounts) using MailKit .NET the recipient recieves the mail in a new, empty thread.

Doing this through the Gmail website manually does thread the mail correctly though. The recipient recieves the mail in the thread with the rest of the conversation.

However, answering the latest mail in a thread does thread correctly for the recipient.

This is my method

public void Send(string InReplyTomessageId, string Reciever, string Message, string smtpServer, string smtpUser, string smtpPass) {
    var emailMessage = new MimeMessage();
    emailMessage.From.Add(new MailboxAddress(smtpUser));
    emailMessage.To.Add(new MailboxAddress(Reciever));
    
    emailMessage.Subject = "This is a test email";
    emailMessage.InReplyTo = InReplyTomessageId;
    emailMessage.References.Add(InReplyTomessageId);

    emailMessage.Body = new TextPart("plain")
    {
        Text = Message
    };

    using (var client = new SmtpClient())
    {
        client.Connect(smtpServer, 465, MailKit.Security.SecureSocketOptions.SslOnConnect);

        client.Authenticate(smtpUser, smtpPass);

        client.Send(emailMessage);
        Console.WriteLine("Email sent successfully!");
        
        client.Disconnect(true);
    }
}

I make sure to use both In-Reply-To and References. I find the MessageId by looking under Show original on the Gmail website.

Is there something I missed in my method that makes threading fail? Or is it just not possible? This issue is not only apparent when sending to Gmail.


Solution

  • There are a few things you need to do to make replies thread correctly:

    1. The reply Subject string should be the original message's Subject header prefixed with "Re: ":
    reply.Subject = "Re: " + original.Subject;
    
    1. You need to set the In-Reply-To header of the reply (like you are doing) to the original message's Message-Id header:
    reply.InReplyTo = original.MessageId;
    
    1. You need to copy all of the original message's References to the reply message's References:
    foreach (var reference in original.References)
        reply.References.Add (reference);
    
    1. Then you need to append the original message's Message-ID to the reply message's References:
    reply.References.Add (original.MessageId);
    

    This should result in a properly threaded message conversation.