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"<UUID@senderdomain.com>"
(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,"<a484d2d2-9d4f-11ed-a8fc-0242ac120002@sender.com>"
. 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": "sender@example.com"},
"to": {"address": "recipient@example.com"},
"subject": "Test message thread",
"html": "<p>First message in thread!</p>",
"messageId": "<first-message@example.com>"
}
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": "sender@example.com"},
"to": {"address": "recipient@example.com"},
"subject": "Test message thread",
"html": "<p>Second message in thread!</p>",
"messageId": "<second-message@example.com>",
"headers": {
"references": "<first-message@example.com>"
}
}
For the third email, the references value would look like this:
"references": "<first-message@example.com> <second-message@example.com>"
This would nicely group all our follow-up emails in a single thread for most email clients.