Search code examples
node.jsmailgunalexa-skills-kitalexa-sdk-nodejs

Unable to send Email from Lambda function created for Alexa skill using Mailgun node package


I am trying to send Email notification to Mailgun(Authorized ID) from an alexa skill. The code is working fine when launched isolated in node environment. But fails to send the Mail when executed on Lambda.

Here is the code segment:

var User= this.attributes['UserName']; /*session variable is working fine...*/
var data = {
 from: 'xxxxxxxx', /*Mailgun sandbox*/
 to: 'zzzzzzzz', /* Authorized mail ID*/
 subject: 'Request',
 text: `Hi, ${Alias} is waiting for you.`
};

mailgun.messages().send(data, function(error, body) {
  console.log(body);
});

this.response.speak('A message has been sent to ${User}.');
this.emit(':responseReady');

EDIT: My environment variables are set properly as:

/* Parameters for MAILGUN*/
var api_key = process.env.MAILGUN_API_KEY;
var domain = process.env.MAILGUN_DOMAIN;
var mailgun = require('mailgun-js')({apiKey: api_key, domain: domain});

Lambda function is set correctly as:

exports.handle = function(event, context) { /* "index.handler" would call 
exports.handler in index.js.*/
var alexa = Alexa.handler(event, context);
alexa.appId = appId;
alexa.registerHandlers(newSessionHandler, greetingHandler, aliasHandler, addressHandler, daysHandler1, accessHandler,  daysHandler2, hostnameHandler, hostHandler, facilityHandler1, facilityHandler2, hsschrHandler, hsschostHandler); /* List of handlers */
alexa.execute();

};

There is no problem with lambda code execution, entire code gets executed and the response is received from Alexa like "A message has been sent". But actually it is not. Ideally it should first send the mail and then emit the response.

I am using Apex for lambda deployment and i have correctly set environment variable in project.json as "environment":

{
  "MAILGUN_API_KEY": "${MAILGUN_API_KEY}",
  "MAILGUN_DOMAIN": "${MAILGUN_DOMAIN}"
}

Solution

  • I can't say why the emails are not being sent, but my suggestion would be to re-structure the code a bit like this:

    mailgun.messages().send(data, (error, body) => {
      if (error) {
        console.log('something went wrong');
        console.log(error);
      } else {
        console.log('message sent')
        console.log(body);
        this.response.speak('A message has been sent to ${User}.');
        this.emit(':responseReady');
      }
    });
    

    A couple things to note:

    • this.response.speak and this.emit now happen within the callback function, so Alexa will only speak after the message is successfully sent, which it looks like is your desired behavior
    • I changed the callback function from a standard function(error, body) {} to an arrow function (error, body) => {}. This basically allows you to use this within the callback and it references the this from the outer scope

    If there is still an issue sending the message, at least now it will be logged and you can debug further.