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:
- 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.
- Set a
messageId
property (which will end up as theMessage-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 generatedmessageId
values somewhere so you would know which value corresponds to which email - Starting from the second email, you have to set a custom header
"headers": {"references": "reflist"}
where reflist is a space-separated list of all previousmessageId
values in the same thread.
Pay attention to themessageId
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.