This is the first function, with missions:
Because many reasons:
ExtractEmailLambda
, because i our code is use nodejs so we choose Nodejs 22.x. Then we choose existing role ExtractEmailFunctionRole
then click Create functionUpload successful
Next, we need to config environment variable for our function to interact with other service
Key | Value | Description |
---|---|---|
QUEUE_NAME | sqs-generate-email-content-queue | This is the queue name we will send message (email content) to generate response |
BUCKET_NAME | ai-powered-email-auto-replies | This bucket for getting email content, because SES not emit email content, it just emit the messageId (the key of the email object in our bucket) |
Click Save
Configuration | Value | Description |
---|---|---|
function_name | ExtractEmailLambda | The unique name identifier for the Lambda function |
role | ExtractEmailFunctionRole | IAM role that defines the permissions and access policies for the function |
runtime | nodejs20.x | The execution environment and version for the Lambda function (Node.js 20) |
handler | index.handler | The entry point for the function |
memory_size | 128 | Amount of memory allocated to the function in MB (128MB) |
timeout | 30 | Maximum execution time allowed for the function in seconds |
// Helper function to extract email data from SES event
const extractEmailData = async (event: SESEvent) => {
const sesRecord = event.Records[0].ses;
const messageId = sesRecord.mail.messageId;
const emailData = {
sender: sesRecord.mail.source,
key: messageId,
};
// Get email content from S3
const getObjectCommand = new GetObjectCommand({
Bucket: env.bucketName,
Key: `received-email/${messageId}`
});
const response = await s3Client.send(getObjectCommand);
const emailContent = await response.Body?.transformToString();
// Parsing MIME type to JSON object
const { text, subject } = await simpleParser(emailContent);
return {
...emailData,
subject,
content: text || "No email data"
};
};
const body = await extractEmailData(event);
const command = new GetQueueUrlCommand({ // GetQueueUrlRequest
QueueName: env.queueName, // required
});
const queueUrlResponse = await sqsClient.send(command);
const params = {
QueueUrl: queueUrlResponse.QueueUrl,
MessageBody: JSON.stringify(body),
};
await sqsClient.send(new SendMessageCommand(params));
Full source code
import { Handler, SESEvent } from 'aws-lambda';
import { GetQueueUrlCommand, SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { Logger } from '@aws-lambda-powertools/logger';
import * as mailparser from 'mailparser';
require('dotenv').config();
const simpleParser = mailparser.simpleParser;
const logger = new Logger();
const env = {
queueName: process.env.QUEUE_NAME || "",
bucketName: process.env.BUCKET_NAME || ""
}
const sqsClient = new SQSClient();
const s3Client = new S3Client();
// Helper function to extract email data from SES event
const extractEmailData = async (event: SESEvent) => {
const sesRecord = event.Records[0].ses;
const messageId = sesRecord.mail.messageId;
const emailData = {
sender: sesRecord.mail.source,
key: messageId,
};
// logger.info("Email Data: ", JSON.stringify(emailData, null, 2));
// Get email content from S3
const getObjectCommand = new GetObjectCommand({
Bucket: env.bucketName,
Key: `received-email/${messageId}`
});
const response = await s3Client.send(getObjectCommand);
const emailContent = await response.Body?.transformToString();
const { text, subject } = await simpleParser(emailContent);
return {
...emailData,
subject,
content: text || "No email data"
};
};
export const handler: Handler = async (event: SESEvent): Promise<void> => {
try {
const body = await extractEmailData(event);
// logger.info({
// message: "Extracted email data",
// body: body
// });
const command = new GetQueueUrlCommand({ // GetQueueUrlRequest
QueueName: env.queueName, // required
});
const queueUrlResponse = await sqsClient.send(command);
const params = {
QueueUrl: queueUrlResponse.QueueUrl,
MessageBody: JSON.stringify(body),
};
await sqsClient.send(new SendMessageCommand(params));
}
catch (error) {
logger.error(error as string);
}
};
TriggerEmailIncoming
and choose Create rule setExtractAndSaveToS3
and choose NextExtractEmailLambda
and add another action to save email to S3received-email
. We also provide them a policy to allow SES put object to S3, choose Create IAM RoleSESSaveEmailToS3Role
and Create roleSESSaveEmailToS3Policy
from the search box > SESSaveEmailToS3Policy > Add permissions