2

When I make a call to ses.sendEmail the promise is never called. This is function in my lambda layer being called by my lambda function.

Here's the sendEmail function I have..

var aws = require ('aws-sdk')
var ses = new aws.SES ({region: 'us-west-2'});

exports.sendEmail = async (to, from, subject, body) => {

var params = {
    Destination: {
        ToAddresses : [to]
    },
    Message: {
        Body: {
            Html: { 
                Charset: "UTF-8",
                Data : body
            }
        },
        Subject: {
            Charset: "UTF-8",
            Data : subject
        }
    },
    Source: from
}

console.log ("Sending email with params (stringify) : ", JSON.stringify(params));

console.log ("SES = ", ses);

await ses.sendEmail (params, function (err, data) {

    console.log ("inside email");
});
}

I see the "Sending email with params (stringify)" log output and the "SES = " log output (which shows what appears to be a valid SES). But I never see "inside email" in the log nor do I receive any emails.

I'm also outside of the ses sandbox as I've gotten approval after setting up my domain and successfully verifying it all. I am on the us-west-2 region. I have not verified any email addresses. Just the domain (ie. name@user.host... user.host is verified) as I assumed if the domain is verified then any email from that domain should be good for use in the "from".

Etep
  • 533
  • 7
  • 20
  • https://stackoverflow.com/questions/51328292/how-to-use-async-and-await-with-aws-sdk-javascript/51328537#51328537 – hoangdv Jan 16 '22 at 09:25

3 Answers3

2

I have used async await instead of promises. I was facing the same issue. Email is dispatched successfully in my local computer but when I deploy the lambda and start testing it live. Emails were not sent to the email address mentioned.

    async function sendMail(content, email) {      
const params = {
        Destination: {
            ToAddresses: [email.toLowerCase()],
        },
        Message: {
            Body: {
                Text: {
                    Charset: "UTF-8",
                    Data: content.text,
                },
                Html: {
                    Charset: "UTF-8",
                    Data: content.html,
                },
            },
            Subject: {
                Charset: "UTF-8",
                Data: content.subject,
            },
        },
        Source: secretManagerData.senderEmail,
    };

    const sendPromise = await AWS_SES.sendEmail(params).promise();
    console.log(sendPromise);
   }
Ankit Kumawat
  • 371
  • 5
  • 13
0

There are mistakes in calling the functions. When you call the function, you don't need to give a space with it.

var aws = require('aws-sdk'); // these are functions, call them without space 
var ses = new aws.SES({region: 'us-west-2'}); // this

exports.sendEmail = async (to, from, subject, body) => {

try {
var params = {
    Destination: {
        ToAddresses : [to]
    },
    Message: {
        Body: {
            Html: { 
                Charset: "UTF-8",
                Data : body
            }
        },
        Subject: {
            Charset: "UTF-8",
            Data : subject
        }
    },
    Source: from
}

console.log("Sending email with params (stringify) : ", JSON.stringify(params));

console.log("SES = ", ses);

const data = await sendmail(params);
return data;
} catch (e) {
   console.log(e);
}
}

const sendmail = (params) => {
   return new Promise((res, rej) => {
        sendEmail(params = {}, (err, data)=>{
          if (err) rej(err);
          else res(data);
       }) 
   })
}

When you have to use async/await, you don't need to use callback and always use try/catch with async/await.

Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
  • While you are right with the `aysnc/await` part, your answer is not entirely correct. `sendEmail` does not return a promise, see: https://stackoverflow.com/questions/51328292/how-to-use-async-and-await-with-aws-sdk-javascript/51328537#51328537 And I have no idea what should this mean: "When you call the function, you don't need to give a space with it" – Ervin Szilagyi Jan 16 '22 at 09:44
  • The SO used async/await with the callback, so I corrected it. I haven't validated the `sendEmail` function, but I will update the correct version of this function. – Apoorva Chikara Jan 16 '22 at 11:54
  • So I've made changes as you've stated. I thought AWS's SES did return a promise according to their docs. But regardless I have it setup as you've suggested. It's all going through but no email is sent. I thought this might be an issue due to my lambda being in a VPC to access RDS. So I setup VPC endpoints just now to access SES in the same security group I've always been using. But still no email is being sent. I found this SO that suggested this as a possible issue : https://stackoverflow.com/questions/43990264/ses-sendmail-inside-a-aws-lambda-function-not-returning-callback But still no go. – Etep Jan 16 '22 at 19:47
0

I got somehow same issue, it was resolved after used await before invoke sendEmail with promise and added API-Version for SES object.

const AWS = require ('aws-sdk')
const SES = new AWS.SES({apiVersion: '2010-12-01'});
try{
await SES.sendEmail(params).promise();
      console.log("Email sent successfully");
}catch(err){
       console.log("Failed to send email");
}
Gowtham
  • 499
  • 6
  • 9