Alexa skill to get data from web api

Alexa skill to get data from web api




How to create alexa with lambda function calling web api using node.js




Click on create skill in order to create a new skill



Type skill name and choose custom skill.


Click on Create skill

Choose template - start  from scratch


Click on Invocation - select invocation name by which alexa will point to.


Click on Intent then choose add intent



Create a name for intent which will act as parameter checker in lamda function



Add Sample uttrances which will work as aliase for your intent.



To see the sample json for uttrances - Click on JSON Editor


{
    "interactionModel": {
        "languageModel": {
            "invocationName": "myzingonline",
            "intents": [
                {
                    "name": "AMAZON.FallbackIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "GetProteinIntake",
                    "slots": [],
                    "samples": [
                        "my today protien",
                        "tell me about my protien"
                    ]
                }
            ],
            "types": []
        }
    }
}

Adding to inbuilt intent - By clicking on particular intent




Click on Add


And choose existing intent



Create a Skill service






Choose Author from scratch add function name and runtime as Nodejs xx version number



Choose permission to existing  role with basic execution



Click on Create function. It will show screen like this



Add trigger  - Alexa skills kit


We need to add skill id in order to use Alexa skills kit




In order to get skill id we need to go to our skill page.
go to https://developer.amazon.com/alexa/console/ask





We need to copy and paste it to lambda trigger.

amzn1.ask.skill.16558811-1b0c-43cc-973b-f4b2054fa4c3




Click on Lambda function in order to configure it.


It will show


Note : So if you need to use web service we need to upload nodmodule with request dll.

So choose upload a .zip file


We need to zip inside this and then upload it as zip folder.



Now click save to upload the zip folder.



After save



var request = require("request")

// 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.
         */

    // if (event.session.application.applicationId !== "") {
    //     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) {
    // add any session init logic here
}

/**
 * Called when the user invokes the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    getWelcomeResponse(callback)
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {

    var intent = intentRequest.intent
    var intentName = intentRequest.intent.name;

    // dispatch custom intents to handlers here
    if (intentName == "GreetHelloWorld") {
        handleGetInfoIntent(intent, session, callback)
    } else {
         throw "Invalid intent"
    }
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {

}

// ------- Skill specific logic -------

function getWelcomeResponse(callback) {
    var speechOutput = "Welcome! Do you want to hear about some facts?"

    var reprompt = "Do you want to hear about some facts?"

    var header = "Get Info"

    var shouldEndSession = false

    var sessionAttributes = {
        "speechOutput" : speechOutput,
        "repromptText" : reprompt
    }

    callback(sessionAttributes, buildSpeechletResponse(header, speechOutput, reprompt, shouldEndSession))

}

function handleGetInfoIntent(intent, session, callback) {

    var speechOutput = "We have an error"

    getJSON(function(data) {
        if (data != "ERROR") {
            var speechOutput = data
        }
        callback(session.attributes, buildSpeechletResponseWithoutCard(speechOutput, "", true))
    })

}

function url() {
    return "http://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=Albert+Einstein"
}

function url2() {
    return {
        url: "https://api.nytimes.com/svc/books/v3/lists.json",
        qs: {
            "api-key" : "8430ae194d0a446a8b1b9b9d607b2acc",
            "list" : "hardcover-fiction"
        }
    }
}

function getJSON(callback) {
    //HTTP - WIKPEDIA
    request.get(url(), function(error, response, body) {
        var d = JSON.parse(body)
        var result = d.query.searchinfo.totalhits
        if (result > 0) {
            callback(result);
        } else {
            callback("ERROR")
        }
    })

    // HTTPS with NYT
    // request.get(url2(), function(error, response, body) {
        // var d = JSON.parse(body)
        // var result = d.results
        // if (result.length > 0) {
            // callback(result[0].book_details[0].title)
        // } else {
            // callback("ERROR")
        // }
    // })
}


// ------- Helper functions to build responses for Alexa -------


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

function buildSpeechletResponseWithoutCard(output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    };
}

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

function capitalizeFirst(s) {
    return s.charAt(0).toUpperCase() + s.slice(1)
}

Add intent name to onIntent method according to your intent name.






/**
 * Called when the user specifies an intent for this skill.
 */

function onIntent(intentRequest, session, callback) {

    var intent = intentRequest.intent
    var intentName = intentRequest.intent.name;

    // dispatch custom intents to handlers here
    if (intentName == "GreetHelloWorld") {
        handleGetInfoIntent(intent, session, callback)
    } else {
         throw "Invalid intent"
    }
}


So whenever any uttrence will match from alexa skill it send the Intentname to lamda function and then we can write logic for giving the response.







that is using .get method of request library in node.js which gets the information from give url.


Web api is returning 


So we need to parse the data accordingly


Click Save to save the changes.

full index.js


var request = require("request")

// 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.
         */

    // if (event.session.application.applicationId !== "") {
    //     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) {
    // add any session init logic here
}

/**
 * Called when the user invokes the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    getWelcomeResponse(callback)
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {

    var intent = intentRequest.intent
    var intentName = intentRequest.intent.name;

    // dispatch custom intents to handlers here
    if (intentName == "GetProteinIntake") {
        handleGetInfoIntent(intent, session, callback)
    } else {
         throw "Invalid intent"
    }
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {

}

// ------- Skill specific logic -------

function getWelcomeResponse(callback) {
    var speechOutput = "Welcome! Do you want to hear about some facts?"

    var reprompt = "Do you want to hear about some facts?"

    var header = "Get Info"

    var shouldEndSession = false

    var sessionAttributes = {
        "speechOutput" : speechOutput,
        "repromptText" : reprompt
    }

    callback(sessionAttributes, buildSpeechletResponse(header, speechOutput, reprompt, shouldEndSession))

}

function handleGetInfoIntent(intent, session, callback) {

    var speechOutput = "We have an error"

    getJSON(function(data) {
        if (data != "ERROR") {
            var speechOutput = data
        }
        callback(session.attributes, buildSpeechletResponseWithoutCard(speechOutput, "", true))
    })

}

function url() {
    return "http://foodlogger-api.myzingonline.com/api/food/getalexa1"
}

function url2() {
    return {
        url: "https://api.nytimes.com/svc/books/v3/lists.json",
        qs: {
            "api-key" : "8430ae194d0a446a8b1b9b9d607b2acc",
            "list" : "hardcover-fiction"
        }
    }
}

function getJSON(callback) {
    //HTTP - WIKPEDIA
    request.get(url(), function(error, response, body) {
        var d = JSON.parse(body)
        var result = d.name
        if (result.length > 0) {
            callback(result);
        } else {
            callback("ERROR")
        }
    })

    // HTTPS with NYT
    // request.get(url2(), function(error, response, body) {
        // var d = JSON.parse(body)
        // var result = d.results
        // if (result.length > 0) {
            // callback(result[0].book_details[0].title)
        // } else {
            // callback("ERROR")
        // }
    // })
}


// ------- Helper functions to build responses for Alexa -------


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

function buildSpeechletResponseWithoutCard(output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    };
}

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

function capitalizeFirst(s) {
    return s.charAt(0).toUpperCase() + s.slice(1)
}


Now we need to add this lambda function as end  point in skill setting.






And add it to Endpoint




Click on Save endpoint


Now Go to Intent and click on build model



Now Click on Test to test skill.



ask myzingonline my today protien



Change some function logic in lambda


Click save and re run test




Share on Google Plus

About myzingonline

Myzingonline is all about zing to share experience, knowledge, likes, dislikes and ideas of a person to the world.
    Blogger Comment
    Facebook Comment

0 comments:

Post a Comment