0
votes

I have a lambda function that is connected to an Alexa skill. At the start of the skill I want to store a string to dynamoDB. Therefore I call a function directly in the launch request (the function is called nameExport()). However the function is only stores something if I delete the "this.emit" command in the launch request. If I leave "this.emit" the skill is working but nothing is stored to the database. Below you find the code concerning LaunchRequest as well as the function to store into dynamoDB.

var config = require("config");
var Alexa = require("alexa-sdk");
var AWS = require("aws-sdk");
var Speech = require("ssml-builder");
var dynamodb = new AWS.DynamoDB();

let handlers = {
    'LaunchRequest': function () {
        nameExport("testName");
        let speech = new Speech ();
        speech.say("Welcome by Emotions.")
        speech.pause("100ms")
        speech.say("Do you want to assess your current emotion?")
        let speechOutput = speech.ssml(true);
        this.emit(":ask", speechOutput)
    },
    'Emotion': function () {
        let speech = new Speech();
        ...

The nameExport function that should write the String into the database:

function nameExport(name) {
    var tableName = "myinfo";
    dynamodb.putItem({
            "TableName": tableName,
            "Item": {
                "name": {
                    "S": name
                }
            }
        }, function(err, data) {
            if (err) {
                //context.fail('ERROR: Dynamo failed: ' + err);
            } else {
                console.log('Dynamo Success: ' + JSON.stringify(data, null, '  '));
                //context.succeed('SUCCESS');
            }
        });
};   
1

1 Answers

0
votes

this.emit just finishes lambda execution and putItem function cannot be finished in its scope. You should call this.emit when putItem finishes.

You can achieve that by using async/await (make sure, that lambda uses node.js v8.10):

'LaunchRequest': async function () {
        await nameExport("testName");
        let speech = new Speech ();
        speech.say("Welcome by Emotions.")
        speech.pause("100ms")
        speech.say("Do you want to assess your current emotion?")
        let speechOutput = speech.ssml(true);
        this.emit(":ask", speechOutput)
    },

async function nameExport(name) {
    var tableName = "myinfo";
    return new Promise((resolve, reject) => { dynamodb.putItem({
            "TableName": tableName,
            "Item": {
                "name": {
                    "S": name
                }
            }
        }, function(err, data) {
            if (err) {
                reject(err);
            } else {
                console.log('Dynamo Success: ' + JSON.stringify(data, null, '  '));
                resolve();
            }
        })});
};  

Or without async/await by emitting ":ask" in callback, which is not so gentle solution:

'LaunchRequest': function () {

        let speech = new Speech ();
        speech.say("Welcome by Emotions.")
        speech.pause("100ms")
        speech.say("Do you want to assess your current emotion?")
        let speechOutput = speech.ssml(true);
        nameExport("testName", () => this.emit(":ask", speechOutput));
    },

function nameExport(name, callback) {
    var tableName = "myinfo";
    return new Promise((resolve, reject) => { dynamodb.putItem({
            "TableName": tableName,
            "Item": {
                "name": {
                    "S": name
                }
            }
        }, function(err, data) {
            if (err) {
                // some error handling
            } else {
                callback()
            }
        })});
};  

By the way - there is an Alexa SDK 2.0 - 1.0, that you want to use is no longer supported. I would recommend to switch to the latest version (by re-writing the code or by using an adapter)