AWS SES sends mails with a custom Reference header
- Published on
- Authors
- Name
- Binh Bui
- @bvbinh
Photo by Mathyas Kurmann
Use case: Group emails by a thread
Sometimes you want mail clients to group emails into threads. For example, if you have a group of emails that are related to the same topic, you want to mail client to group them together when user view the list of emails in threaded view.
Like this one:
Solution
There are a few ways around this / to work with this.
- Use
In-Reply-To
header. If the email is a reply to another email, you can use theIn-Reply-To
header to group the emails together. - Use
References
header to group emails together.
In my case, I use the second method.
Add custom headers to the email in AWS SES
To add custom headers to the email, I used sendRawEmail
instead of sendEmail
method. Below is full example of how to add custom headers to the email.
import AWS from 'aws-sdk'
const { SES } = AWS
// update the following variables with the values from your configuration
AWS.config.update({ region: 'region' })
const fromEmail = 'Info <from@example.com>'
const to = 'to@yourdomain.com'
// fixed a reference id for testing. Replace with your own topic reference id
const TOPIC_REFERENCE = '<111111@example.com>'
// Subject of the email, append the date to the subject. This make subject unique every time the email is sent
const subject = `Test email from AWS SES!!! ${new Date()}`
const plainText = `Hello from AWS SES! ${new Date()}`
const html = `<h1>Hello from AWS SES!</h1> <span>${new Date()}</span>`
const ses = new SES({ apiVersion: '2010-12-01' })
const sendRawMessage = async () => {
// Set up from_name, from_email, to, subject, message_id, plain_text, html and configuration_set variables from database or manually
const boundary = `----=_Part${Math.random().toString().substr(2)}`
const rawMessage = [
`From: ${fromEmail}`, // Can be just the email as well without <>
`To: ${to}`,
`Subject: ${subject}`,
`MIME-Version: 1.0`,
// `Message-ID: <${ message_id }@eu-west-1.amazonses.com>`, // Will be replaced by SES
// `Date: ${ formatDate( date ) }`, // Will be replaced by SES
// `Return-Path: <${ message_id }@eu-west-1.amazonses.com>`, // Will be replaced by SES
`Content-Type: multipart/alternative; boundary="${boundary}"`, // For sending both plaintext & html content
// ... you can add more headers here as described in https://docs.aws.amazon.com/ses/latest/DeveloperGuide/header-fields.html
`References: ${TOPIC_REFERENCE}`,
`\n`,
`--${boundary}`,
`Content-Type: text/plain; charset=UTF-8`,
`Content-Transfer-Encoding: 7bit`,
`\n`,
plainText,
`--${boundary}`,
`Content-Type: text/html; charset=UTF-8`,
`Content-Transfer-Encoding: 7bit`,
`\n`,
html,
`\n`,
`--${boundary}--`,
]
// Send the actual email
return ses
.sendRawEmail({
Destinations: [to],
RawMessage: {
Data: rawMessage.join('\n'),
},
Source: fromEmail, // Must be verified within AWS SES
// ConfigurationSetName: 'ConfigurationSetName', // optional AWS SES configuration set for open & click tracking
Tags: [
// ... optional email tags
],
})
.promise()
}
You can download sample code here
References
https://www.ietf.org/rfc/rfc0822.txt
https://www.hostknox.com/tutorials/email/headers
https://docs.aws.amazon.com/ses/latest/dg/header-fields.html