简体   繁体   中英

AWS Lambda not firing Email via nodemailer, but does in the local development environment

I'm working on a aws-lambda which is supposed to shoot mail when an event is triggered. I using nodejs for this and below is the code:

"use strict";


exports.sendEmail = function(event, context, callback) {
    var config = require('./config');
    var fs = require('fs');
    var _ = require('lodash');

    if (_validSchema(event.payload)) {
        var templatePath = config.schemaMapping[event.payload.emailDetails.emailType]["templatePath"]
        var emailHTML = _getHTML(templatePath, event.payload.params)
        if (emailHTML && templatePath) {
            _sendSESEmail(_emailParams(event.payload.emailDetails), emailHTML)
            context.succeed(JSON.stringify(_setResponse(200, [{
                code: "11",
                source: "Email template or Email params in payload",
                message: "Please provide correct Email template and correct email params",
                detail: "Template path is provided via config and Params via Payload"
            }])));
        } else
            context.fail(JSON.stringify(_setResponse(400, [{
                code: "01",
                source: "Email template or Email params in payload",
                message: "Please provide correct Email template and correct email params",
                detail: "Template path is provided via config and Params via Payload"
            }])));
    } else {
        context.fail(JSON.stringify(_setResponse(400, [{
            code: "02",
            source: "Payload schema",
            message: "Please provide correct schema to validate and a payload validating it",
            detail: "Payload is provided "
        }])));
    }


    function _validSchema(payload) {
        var schemaPath = config.schemaMapping[payload.emailDetails.emailType]["schemaPath"];
        var payloadVerification = _verifyPayload(payload, schemaPath);
        console.log(payloadVerification.valid);
        return payloadVerification.valid;
    }

    function _emailParams(emailDetails) {
        var details = {};
        details.to = _.join(emailDetails.to, ',');
        details.from = emailDetails.from;
        details.cc = _.join(emailDetails.cc, ',');
        details.bcc = _.join(emailDetails.bcc, ',');
        details.attachments = emailDetails.attachments;
        details.subject = emailDetails.subject;
        return details;
    }

    function _verifyPayload(payload, schemaPath) {
        var schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));
        var Validator = require('jsonschema').Validator;
        var verifier = new Validator();
        console.log(verifier.validate(payload, schema))
        return verifier.validate(payload, schema);
    }

    function _setResponse(status_code, error_list) {
        return {
            status: status_code,
            errors: error_list
        };
    }

    function _sendSESEmail(email, emailHTML) {
        var nodemailer = require('nodemailer');
        var sesTransport = require('nodemailer-ses-transport');
        var transporter = nodemailer.createTransport(sesTransport({
            accessKeyId: config.SES.accessKeyId,
            secretAccessKey: config.SES.secretAccessKey
        }));
        transporter.sendMail({
            from: email.from,
            to: email.to,
            cc: email.cc,
            bcc: email.bcc,
            attachments: email.attachments,
            subject: email.subject,
            html: emailHTML
        });
    }

    function _getHTML(templateFile, params) {
        var ejs = require('ejs');
        console.log({ params: params })
        var baseHTML = fs.readFileSync(templateFile, 'ascii');
        return ejs.render(baseHTML, { params: params });
    }
}

Above code works fine when tested in the dev environment with the below code, but does not fire a mail when tested on aws-lamda.

"use strict";

var exports = require('./exports');

var bankDetailsSchemaSample = {
    "payload": {
        "emailDetails": {
            "from": 'some@something.com',
            "to": ['kunal@something.com'],
            "subject": 'My Amazon SES Simple Email',
            "html": '',
            "cc": ['nimesh.verma@something.com'],
            "bcc": ['lokesh.gour@something.com'],
            "emailType": 'bankDetails',
            "attachments": [{
                "filename": 'test.md',
                "path": 'https://raw.github.com/nodemailer/nodemailer/master/LICENSE'
            }]
        },
        "params": {
            "orderId": 1234567,
            "firstName": "Nimesh",
        }
    }
}

var context = {
    fail: function(x) { console.log(" Fail " + x) },
    succeed: function(x) { console.log(" Success " + x) }
}

exports.sendEmail(bankDetailsSchemaSample, context, {})

I can't find out, why this is happening, I also tried it using nodemailer-smtp-transport instead of nodemailer-ses-transport but the same results were obtained. When nothing helped I tried using aws-sdk instead of nodemailer and nodemailer-ses-transport and the mail is fired in both dev environment as well via aws lamda testing.

// load aws sdk
exports.sendEmail = function(event, context, callback) {
    var aws = require('aws-sdk');

    // load aws config
    aws.config.loadFromPath('config.json');

    // load AWS SES
    var ses = new aws.SES({ apiVersion: '2010-12-01' });

    // send to list
    var to = ['nimesh.verma@something.com']

    // this must relate to a verified SES account
    var from = 'some@something.com'


    // this sends the email
    // @todo - add HTML version
    ses.sendEmail({
        Source: from,
        Destination: { ToAddresses: to },
        Message: {
            Subject: {
                Data: 'A Message To You Rudy'
            },
            Body: {
                Text: {
                    Data: 'Stop your messing around',
                }
            }
        }
    }, function(err, data) {
        if (err) throw err
        console.log('Email sent:');
    });
}

Why is this happening?

The problem was that the context.succeed method should be placed in the callback of _sendSESEmail method.

The complete working code is present at: https://github.com/nimeshkverma/aws-lambda-node-mailer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM