AWS SES: How to send a mail with an attachment in Node.js

Sateesh Gandipadala
Nov 6 · 3 min read
Image for post
Image for post
Image source: wallpaperaccess

In this article, I will explain how to send attachments using AWS SES and this article is for the people who already know how to send a simple email using SES.

SES allows sending attachments only through sendRawEmail method.

sendRawEmail accepts Multipurpose Internet Mail Extensions (MIME) type email body as data, so let's see how to prepare MIME type email content.

Image for post
Image for post

A typical MIME email looks like the above example, it is a multipart email with the content in both HTML format and text format and it contains a text file as an attachment.

We can create a string like the above example and send as data to sendRawEmail, but it will be very confusing to format this long string. To simplify the MIME body creation we can use npm module like mimemessage. Install the mimemessage npm module as shown below.

npm i mimemessage

mimemessage module helps us in creating the email with less hassle. First, we need to create mailContent using mimemessage factory method as shown below. All the mail content will be attached to this object.

var mimemessage = require('mimemessage');var mailContent = mimemessage.factory({contentType: 'multipart/mixed',body: []});

Now, let us add the headers to this.

mailContent.header('From', 'Sender Name <sender@example.com>');
mailContent.header('To','recipient@example.com');
mailContent.header('Subject', 'Customer service contact info');

Now, we added the headers, let us add the mail content. Using MIME email type we can add both text and HTML variation of the same email content. To have both variations first we need to create a multipart/alternative object.

var alternateEntity = mimemessage.factory({
contentType: 'multipart/alternate',
body: []
});

Now we need to create both HTML and text entities and add to the above alternateEntity.

var htmlEntity = mimemessage.factory({
contentType: 'text/html;charset=utf-8',
body: ' <html> ' +
' <head></head> ' +
' <body> ' +
' <h1>Hello!</h1> ' +
' <p>Please see the attached file for a list of customers to contact.</p> ' +
' </body> ' +
' </html> '
});
var plainEntity = mimemessage.factory({
body: 'Please see the attached file for a list of customers to contact.'
});
alternateEntity.body.push(htmlEntity);
alternateEntity.body.push(plainEntiFirstty);

Now we need to add this alternateEntity to the mailContent body

mailContent.body.push(alternateEntity);

We will be adding attachment also as a part to the main mailContent object. First, we need to read the file and convert the file content into a base64 string, add it as the body of this entity. As shown below, we need to specify the type of content and the encoding used. We need to add a header called Content-Disposition with the relevant details.

var data = fs.readFileSync('customers.txt');var attachmentEntity = mimemessage.factory({
contentType: 'text/plain',
contentTransferEncoding: 'base64',
body: data.toString('base64').replace(/([^\0]{76})/g, "$1\n")
});
attachmentEntity.header('Content-Disposition', 'attachment ;filename="customers.txt"');

Now attach this entity to the main mailContent.

mailContent.body.push(attachmentEntity);

Finally, our mail object is ready, we need to pass this to SES sendRawEmail method as shown below.

ses.sendRawEmail({
RawMessage: { Data: mailContent.toString() }
}, (err, sesdata, res) => {
});

If we configure properly we will receive a success message in the callback.

Note: SES allows only 10MB file as an attachment

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store