Alex Vanguard Alex Vanguard - 6 months ago 45
Javascript Question

Amazon Alexa Skill Lambda code won't execute

I am trying to write the Lambda function for an Amazon Alexa skill in NodeJS. Alexa is that cylindrical speaker that responds to your voice, and a "skill" is basically a voice app for it. This function takes the JSON input from the Alexa device and creates a response, then sends the new JSON back to the device for output.

This code is supposed to pull the Bitcoin to USD exchange rate from the BTC-e JSON, extract the 'avg' value, and output it to the Alexa device.

I haven't done any coding in a long time, so please forgive any stupid errors. I took the example code and tried to modify it for my purposes, but I get this error when executing in AWS:

{
"errorMessage": "Unexpected identifier",
"errorType": "SyntaxError",
"stackTrace": [
"Module._compile (module.js:439:25)",
"Object.Module._extensions..js (module.js:474:10)",
"Module.load (module.js:356:32)",
"Function.Module._load (module.js:312:12)",
"Module.require (module.js:364:17)",
"require (module.js:380:17)"
]
}


My code is here. I have a feeling the problem is somewhere in lines 84-106 because that's where I did most of my work.

Thanks for any assistance!

Answer

The code below should work, just un-comment the todo I added. You had a couple of missing braces and I switched to a different http request lib that is included with AWS lambda by default. I also change the flow to make it simpler for me to test, so now it doesn't re-prompt it just tells you the latest bit coin price.

var https = require('https');

// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = function (event, context) {
    try {
        console.log("event.session.application.applicationId=" + event.session.application.applicationId);

        /**
         * Uncomment this if statement and populate with your skill's application ID to
         * prevent someone else from configuring a skill that sends requests to this function.
         */

         // TODO add this back in for your app
        // if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.") {
        //     context.fail("Invalid Application ID");
        // }

        if (event.session.new) {
            onSessionStarted({requestId: event.request.requestId}, event.session);
        }

        if (event.request.type === "LaunchRequest") {
            onLaunch(event.request,
                     event.session,
                     function callback(sessionAttributes, speechletResponse) {
                        context.succeed(buildResponse(sessionAttributes, speechletResponse));
                     });
        }  else if (event.request.type === "IntentRequest") {
            onIntent(event.request,
                     event.session,
                     function callback(sessionAttributes, speechletResponse) {
                         context.succeed(buildResponse(sessionAttributes, speechletResponse));
                     });
        } else if (event.request.type === "SessionEndedRequest") {
            onSessionEnded(event.request, event.session);
            context.succeed();
        }
    } catch (e) {
        context.fail("Exception: " + e);
    }
};

/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId
                + ", sessionId=" + session.sessionId);
}

/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    console.log("onLaunch requestId=" + launchRequest.requestId
                + ", sessionId=" + session.sessionId);

    // Dispatch to your skill's launch.
    getWelcomeResponse(callback);
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
    console.log("onIntent requestId=" + intentRequest.requestId
                + ", sessionId=" + session.sessionId);
    getWelcomeResponse(callback);
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId
                + ", sessionId=" + session.sessionId);
    // Add cleanup logic here
}

// --------------- Functions that control the skill's behavior -----------------------

function getWelcomeResponse(callback) {
        // If we wanted to initialize the session to have some attributes we could add those here.
    var sessionAttributes = {};
    var cardTitle = "Bitcoin Price";
    var speechOutput = "Welcome to the Bitcoin Price skill, "

    var repromptText = ''
    var shouldEndSession = true;

    var options = {
        host: 'btc-e.com',
        port: 443,
        path: '/api/2/btc_usd/ticker',
        method: 'GET'
    };

    var req = https.request(options, function(res) {
        var body = '';
        console.log('Status:', res.statusCode);
        console.log('Headers:', JSON.stringify(res.headers));
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
            body += chunk;
        });
        res.on('end', function() {
            console.log('Successfully processed HTTPS response');

            body = JSON.parse(body);

                console.log(body);
                console.log('last price = ' + body.ticker.last);

                speechOutput += "The last price for bitcoin was : " + body.ticker.last;

                callback(sessionAttributes,
                 buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));

             });
    });
    req.end();

}

// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        card: {
            type: "Simple",
            title: "SessionSpeechlet - " + title,
            content: "SessionSpeechlet - " + output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    }
}

function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: "1.0",
        sessionAttributes: sessionAttributes,
        response: speechletResponse
    }
}
Comments