Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
|
I had a few other ideas for this project, but either ran into API limitations with the platforms I wanted to integrate, or realized - too late - that the scope of the idea was too large for the given timeline.
Nevertheless, I learned some really useful things with this project. I figured out that if you wish to accept a "wild card" utterance, that is, if you wish to let the user say anything in their request, you can use
Intent {key|question}
in your utterances entry or file. This is particularly useful if you are generating random responses from Alexa, as I am in this skill.
I also learned that if you're using node.js and uploading a node_modules folder as part of a .zip to lambda, the folder needs to be world-readable so that AWS can read/find the modules. If you need to store sensitive API keys, you can use the 'dotenv' library, create a .env file, and store your keys there as process.env variables. The 'dotenv' library will read the values from the .env file and you can then reference process.env.whateverYourKeyNameIs in the code rather than hardcode the actual value. This is important when sharing code publicly, like on this site or github.
// 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 !== "amzn1.echo-sdk-ams.app.[unique-value-here]") {
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);
var intent = intentRequest.intent,
intentName = intentRequest.intent.name;
// Dispatch to your skill's intent handlers
if ("CageIntent" === intentName) {
getInsp(intent, session, callback);
} else if ("AMAZON.HelpIntent" === intentName) {
getHelpResponse(callback);
} else if ("AMAZON.StopIntent" === intentName || "AMAZON.CancelIntent" === intentName) {
handleSessionEndRequest(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) {
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 = "Welcome";
var speechOutput = "Welcome to the Brain of Nicolas Cage. " +
"Ask me what you'd like to know and I will respond.";
// If the user either does not reply to the welcome message or says something that is not
// understood, they will be prompted again with this text.
var repromptText = "You can get help by asking, help.";
var shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
function getHelpResponse(callback) {
// If we wanted to initialize the session to have some attributes we could add those here.
var sessionAttributes = {};
var cardTitle = "Help";
var speechOutput = "To use the Brain of Nicolas Cage, you can ask me anything. For example, how do I file something, or, I burned the brisket.";
// If the user either does not reply to the welcome message or says something that is not
// understood, they will be prompted again with this text.
var repromptText = "I'm waiting to mind meld my knowledge into yours.";
var shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
function handleSessionEndRequest(callback) {
var cardTitle = "Session Ended";
var speechOutput = "Goodbye.";
// Setting this to true ends the session and exits the skill.
var shouldEndSession = true;
callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}
function getInsp(intent, session, callback) {
var repromptText = "Speak to me, I'm waiting.";
var sessionAttributes = {};
var shouldEndSession = true;
var speechOutput = "";
var maxLength = 0;
var responseArr = [];
responseArr.push("I'm a vampire! I'm a vampire! I'm a vampire!.");
responseArr.push("I mean, I'll bet no one ever threw a pie at, like Harriet Tubman, the founder of the Underground railroad. I'll bet you a million dollars.");
responseArr.push("You'll be seeing a lot of changes around here. Papa's got a brand new bag.");
responseArr.push("It's like we're on two different channels now. I'm CNN and she's the Home Shopping Network.");
responseArr.push("I have an acronym for myself. Know what it is? B.A.D. B.A.D... Balls, Attitude, Direction. You should give yourself an acronym... 'cause it helps you visualize your goals.");
responseArr.push("If you dress like Halloween, ghouls will try to get in your pants.");
responseArr.push("Face. Off.");
responseArr.push("How could somebody MISFILE something? What could be easier? It's all alphabetical. You just PUT it IN the right file! According to ALPHABETICAL ORDER! You know... A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z! Huh? That's ALL you have to DO!");
responseArr.push("OH, NO! NOT THE BEES! NOT THE BEES! AAAAAHHHHH! OH, THEY'RE IN MY EYES! MY EYES! AAAAHHHHH! AAAAAHHH!");
responseArr.push("Killing me won't bring back your god damn honey!");
responseArr.push("Put... the bunny... back... in the box.");
responseArr.push("I could eat a peach for hours.");
responseArr.push("Pink underwear works. Pink underwear works.");
responseArr.push("I never disrobe before gunplay.");
responseArr.push("HEY! My mama lives in a trailer!");
responseArr.push("Well, Baby O, it's not exactly mai-tais and Yahtzee out here but let's do it.");
responseArr.push("Is this hers? How'd it get burned? How'd it get burned?");
var i = 0;
i = Math.floor((Math.random() * responseArr.length));
speechOutput = responseArr[i];
callback(sessionAttributes,
buildSpeechletResponse("Brain Cage", speechOutput, repromptText, shouldEndSession));
}
// --------------- Helpers that build all of the responses -----------------------
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 buildResponse(sessionAttributes, speechletResponse) {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
}
{
"intents": [
{
"intent": "CageIntent",
"slots": [
{
"name": "question",
"type": "AMAZON.LITERAL"
}
]
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"intent": "AMAZON.CancelIntent"
}
]
}
Comments