使用Lambda,NodeJ和Nodemailer发送电子邮件不起作用

时间:2019-01-21 19:56:04

标签: node.js aws-lambda nodemailer

我正在尝试使用先前经过SES身份验证的帐户从Lambda发送电子邮件;使用Nodemailer使用node.js。没有错误,但没有发送。

这是我正在使用的过程:

module.exports.eviarCorreoPrueba = (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;    
  console.log('inicia envio de correos');    
    var transporter = nodemailer.createTransport({
        //pool: true,
        host: 'email-smtp.us-east-1.amazonaws.com',
        port: 465,
        secure: true,
        auth: {
            user: 'user',
            pass: 'pass'
        }   
    });
    console.log('se crea transporte ');

    var mailOptions = {
        from: 'test@email.com',
        to: 'test@email.com',
        subject: 'Prueba Lambda',          
        html: 'hello World'
    };
    console.log('se asignan las opciones de correo');
    console.log('inicia envio de correo');
    transporter.sendMail(mailOptions, function (error, info) {
        if (error) {
            callback(null, {
              statusCode: 200,
              body: JSON.stringify({
                input: 'not send'
              })
            })
        } else {
            console.log('Email sent');    
        }
    });
    console.log('funcion finalizada');    
};

这些是日志答案结果:

enter image description here

2 个答案:

答案 0 :(得分:2)

以防万一有人陷入“ nodemailer无法在Lambda中工作”的问题:

您帖子中的代码在本地服务器上有效,因为

在您的本地环境中,有一台正在运行的服务器可以调度所有调用堆栈,包括同步和异步任务。在本地环境中调用transporter.sendMail()后,它将放置在当前调用堆栈的末尾,并将执行直到调用堆栈中的最后一次执行完成为止。对于您而言,异步函数transporter.sendMail()将安排在console.log('funcion finalizada');

之后被调用

为什么在Lambda中不起作用

每次调用lambda函数时,它将执行代码,然后在执行完成后终止进程,这意味着它将无法调用异步transporter.sendMail(),因为在{{1}之后} lambda函数过程将被终止,并且计划的异步任务将在执行之前被清除。

要使其在Lambda中工作:

1)将您的功能更改为console.log('funcion finalizada');功能

async

2)等待您的module.exports.eviarCorreoPrueba = async (event, context) => { ... } 被呼叫,然后继续

transporter.sendMail()

3)使nodemailer emailbot正常工作的最后一件事: 您需要打开Less secure app accessAllow access to your Google Account,因为您只是使用用户名和密码来连接Gmail帐户。

*注意:如果您想使用更安全的方法来连接Gmail(例如OAuth 2.0),可以参考我的文章:Create a Free Serverless Contact Form Using Gmail, Nodemailer, and AWS Lambda

希望这对遇到此问题的人有所帮助。

干杯

答案 1 :(得分:0)

您的Lambda超时。查看您的Cloudwatch日志中的最后一条消息。我认为您将lambda超时设置为6秒,我认为这不足以让lambda发送请求(通过transporter.sendMail)并获得响应。尝试增加Lambda时间。大概要30秒?

我为新设计的lambda设置超时的方式是将它们运行几次,直到获得平均完成时间。然后我增加20秒的时间。

此外,transporter.sendMail是异步函数。这意味着console.log('funcion finalizada')可能会在您的函数完成之前运行(但您的函数尚未实际完成)。

详细了解异步javascript和回调:https://medium.com/codebuddies/getting-to-know-asynchronous-javascript-callbacks-promises-and-async-await-17e0673281ee

此外,如果您想以同步方式编写异步代码,请使用async/await