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}"
}
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 behaviorfunction(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 scopeIf there is still an issue sending the message, at least now it will be logged and you can debug further.