Sending multiple emails in the same thread

Sending multiple emails in the same thread

Sometimes you might want to send emails that should end up in the same email thread, for example, follow-up emails. Surprisingly, there is (almost) no server-side threading support. Instead, everything related to threads is handled on the client side. In this case, we would have to compose our emails in a way that would make a regular email client group these emails.

Email threads are basically linked lists, bound together by the References and Message-ID headers. So, to keep the thread, use the following:

  1. For each message in a thread, use the same subject line. You can, but you do not have to use a Re: or an Fwd: prefix. You can just keep the subject unchanged. If you change the subject line (except for the added prefix), you risk breaking the thread.
  2. Set a messageId property (which will end up as the Message-ID header in the email) yourself. Normally, EmailEngine would generate this value automatically, but for custom threads, it would probably be easier to manage those values manually. The format is "<[email protected]>" (including the <> symbols). You would also have to store these generated messageId values somewhere so you would know which value corresponds to which email
  3. Starting from the second email, you have to set a custom header "headers": {"references": "reflist"} where reflist is a space-separated list of all previous messageId values in the same thread.
Pay attention to the messageId format. It must be a globally unique value, and the easiest way to achieve it would be to use a UUID as the local part — for example, "<[email protected]>". Originally the domain part was the local hostname. These days local hostnames mean nothing or look like long hex dumps if you are running your app in a container, so the common practice is to use the same hostname as the sender's email address.

Example

The first email in the thread sets a custom messageId and the initial subject line:

{
  "from": {"address": "[email protected]"},
  "to": {"address": "[email protected]"},
  "subject": "Test message thread",
  "html": "<p>First message in thread!</p>",
  "messageId": "<[email protected]>"
}

The second follow-up email in the same thread sets a messageId and headers.references that includes the messageId value we are trying to follow up to:

{
  "from": {"address": "[email protected]"},
  "to": {"address": "[email protected]"},
  "subject": "Test message thread",
  "html": "<p>Second message in thread!</p>",
  "messageId": "<[email protected]>",
  "headers": {
    "references": "<[email protected]>"
  }
}

For the third email, the references value would look like this:

"references": "<[email protected]> <[email protected]>"

This would nicely group all our follow-up emails in a single thread for most email clients.