Send Email Attachments With The Amazon SES API
SES makes it really easy to send attachments in your emails
Amazon SES or Simple Email Service makes it really easy for developers to send out emails with attachments.
If you use Lambda as a serverless function, that process is made even easier and quicker.
While sending emails with SES is straightforward, many developers run into challenges when setting up their email identities with SES.
In this article, I’ll guide you through setting up an SES identity which you can use to then send out emails with a simple Lambda function.
Setting Up your SES Identity
Let’s start by heading over to the SES service in the AWS console.
In the left hand sidebar, click on Identities and git the Create Identity button.
Select Domain as the identity details and enter domain for the email you wish to use. (e.g. myapp.com for an email like john@myapp.com).
Leave the rest of the configurations at their default. You can click the button at the bottom Create identity.
Next click on the domain to view its details, it will need to be verified.
To verify it, scroll down to the Authentication section. Expand the Publish DNS records element. You will be able to see the CNAME records to add to your hosting provider’s DNS settings.
Once you have done that and the domain has been verified (takes a few minutes only), you can create an email identity under the same domain.
Click the Create identity button again and this time select Email address and enter the email you want to use (this email should be already purchased and registered with your domain hosting provider).
Click Create identity. You will receive an email from AWS to verify your email address. Just click on the link you receive to verify the email address.
Next you will need to request production access.
SES sets your AWS SES account to sandbox by default. You can simply request for production access in the SES dashboard. AWS usually answers quick and provides you production access fairly quickly.
Once that’s done, that’s all you will need to set up SES.
Sending emails with a Lambda function
Let’s now head over to the Lambda service in your AWS console.
Create a new function with the following configuration:
Author from scratch.
name it “send-email”.
Use the Node JS runtime (and arm64 architecture).
Under permissions, add a role for SES full access (guide to do this here).
Once your function is created, scroll down to the code editor and add the following code:
import { SESClient, SendRawEmailCommand } from "@aws-sdk/client-ses";
const sesClient = new SESClient({ region: "us-east-1" });
export const handler = async (event) => {
const { to, subject, bodyText, fileName, fileType, fileBase64 } = JSON.parse(event.body);
const verifiedEmail = hello@myapp.com; //your SES verified email
const boundary = "NextPart_" + new Date().getTime();
const rawMessage = [
`From: ${verifiedEmail}`,
`To: ${to}`,
`Subject: ${subject}`,
`MIME-Version: 1.0`,
`Content-Type: multipart/mixed; boundary="${boundary}"`,
``,
`--${boundary}`,
`Content-Type: text/plain; charset=UTF-8`,
`Content-Transfer-Encoding: 7bit`,
``,
`${bodyText}`,
``,
`--${boundary}`,
`Content-Type: ${fileType}; name="${fileName}"`,
`Content-Description: ${fileName}`,
`Content-Disposition: attachment; filename="${fileName}";`,
`Content-Transfer-Encoding: base64`,
``,
`${fileBase64}`,
``,
`--${boundary}--`,
].join("\r\n");
const command = new SendRawEmailCommand({
RawMessage: { Data: Buffer.from(rawMessage) },
});
try {
const result = await sesClient.send(command);
return {
statusCode: 200,
body: JSON.stringify({ messageId: result.MessageId }),
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify({ error: err.message }),
};
}
};
Hit save and Deploy the code.
Create a Lambda Function URL
Next we will create a function URL to be able to call this function.
In the Configuration tab, click on Function URL in the left hand sidebar.
Click on the Create function URL button.
On this page, select None for the Auth Type. At the bottom check the CORS check box and leave the rest of the configurations as they are.
Once you click on save, you will see a URL endpoint to call this function:
You can now use this endpoint URL in a fetch request on your frontend and pass in the required parameters in the body to call the function and send an email with an attachment.
Here’s an example fetch request to call this endpoint:
const sendEmailWithAttachment = async (file) => {
const reader = new FileReader();
reader.onloadend = async () => {
const base64 = reader.result.split(",")[1];
const payload = {
to: "john@gmail.com",
subject: "Here is your document",
bodyText: "Please find the attachment.",
fileName: file.name,
fileType: file.type,
fileBase64: base64,
};
await fetch("https://your-lambda-url.amazonaws.com/sendEmailWithAttachment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
};
reader.readAsDataURL(file);
};
Run the function and that should send your email.
Conclusion
Sending emails with attachments using Amazon SES and Lambda is an easy and cost-effective solution for developers.
Once your domain and email are verified and production access is granted, integrating SES with a Lambda function URL allows for simple, serverless email sending flows.
With just a few lines of code, you can build a fully functional email service that handles attachments with ease.
👋 My name is Uriel Bitton and I’m committed to helping you master Serverless, Cloud Computing, and AWS.
🚀 If you want to learn how to build serverless, scalable, and resilient applications, you can also follow me on Linkedinfor valuable daily posts.
Thanks for reading and see you in the next one!