在 lambda 中使用 SES 的问题

问题描述 投票:0回答:1

我正在尝试将 SES 发送函数从我的 API 服务器移动到 lambda 函数,SES 在 API 服务器中工作正常,但在 lambda 中不行。

这是设置

  1. 发送 SQS 消息来触发 lambda
  2. Lambda 从消息中提取电子邮件参数(发件人、发件人、主题、电子邮件内容)
  3. 使用SES发送消息

这是其他相关信息

  1. lambda IAM 角色具有完整的 SES 和 SQS 访问权限
  2. 来自电子邮件地址已验证(不在沙箱中)
  3. 标准 lambda 配置(即不附加到任何 VPC)
  4. 这段代码在 lambda 之外也能正常工作。
  5. 我将 lambda 超时从 3 秒(默认)增加到 60 秒。
  6. 我已验证SES命令的参数是否正确

这是代码

import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";

const sesClient = new SESClient({ region: "us-west-2" });

export const handler = async (event) => {
    event.Records.forEach( async (msg) => {

      const args = JSON.parse(msg.body);

      const command = new SendEmailCommand ({
        Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
        Destination: { ToAddresses: [args.recipientEmailAddr] },
        Message: {
          Body: { Text: { Data: args.emailContents } },
          Subject: { Data: args.subject },
        },
      });

      try {
        const resp = await sesClient.send(command);

        console.log('++++++++++++++++++++++++++++++++');
        
        console.log(`Email send response ${resp}`);
        return resp;
      } catch(err) {
        console.log(`Failed to send email - ${err}`);
      } 
    });
};

lambda 运行并退出,没有任何错误,但是,它从不执行 sesClient.send() 命令之后的行

console.log('++++++++++++++++++++++++++++++++');

这告诉我该函数在执行 sesClient.send() 调用期间终止(如果我将控制台语句放在 sesClient.send() 之前,它们会显示在 cloudwatch 日志中。

这是 cloudwatch 命令的输出

INIT_START Runtime Version: nodejs:18.v10   Runtime Version ARN: arn:aws:lambda:us-west-2::runtime:e3aaabf6b92ef8755eaae2f4bfdcb7eb8c4536a5e044900570a42bdba7b869d9
START RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff Version: $LATEST
END RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff
REPORT RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff  Duration: 371.10 ms Billed Duration: 372 ms Memory Size: 128 MB Max Memory Used: 95 MB  Init Duration: 587.21 ms

any idea of what I am doing wrong here??

amazon-web-services aws-lambda amazon-sqs amazon-ses
1个回答
0
投票

在 AWS Lambda 中处理异步代码时存在一个常见问题。代码中的关键问题是将

forEach
与异步函数一起使用。 Lambda 不会等待
forEach
循环中的所有异步操作完成才终止。

结果是 Lambda 函数在启动异步操作后立即完成,而无需等待它们完成。这可能就是您在

sesClient.send()
行之后看不到日志的原因。

要解决此问题,您应该使用

Promise.all
或等待每封电子邮件发送后再继续的循环:

以下是如何修改处理程序以等待使用

Promise.all
发送所有电子邮件:

export const handler = async (event) => {
    const promises = event.Records.map(async (msg) => {

        const args = JSON.parse(msg.body);

        const command = new SendEmailCommand({
            Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
            Destination: { ToAddresses: [args.recipientEmailAddr] },
            Message: {
                Body: { Text: { Data: args.emailContents } },
                Subject: { Data: args.subject },
            },
        });

        try {
            const resp = await sesClient.send(command);
            console.log(`Email send response ${resp}`);
            return resp;
        } catch (err) {
            console.log(`Failed to send email - ${err}`);
        }

    });

    await Promise.all(promises);
    console.log('++++++++++++++++++++++++++++++++');
};

现在,Lambda 函数将等待所有电子邮件发送完成,您应该在发送电子邮件后看到日志。

© www.soinside.com 2019 - 2024. All rights reserved.