Skip to content

Instantly share code, notes, and snippets.

@pkarthikr
Created April 15, 2020 14:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pkarthikr/bce0f42d3022ef6c843fa7a4ae8f9a8d to your computer and use it in GitHub Desktop.
Save pkarthikr/bce0f42d3022ef6c843fa7a4ae8f9a8d to your computer and use it in GitHub Desktop.
Day 3 - Alexa Skills Camp
{
"interactionModel": {
"languageModel": {
"invocationName": "riddle me today",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "RiddleIntent",
"slots": [],
"samples": [
"bring a riddle",
"tell me a riddle",
"what is today's riddle",
"give me today's riddle"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "AMAZON.YesIntent",
"samples": []
},
{
"name": "AnswerIntent",
"slots": [
{
"name": "answer",
"type": "RiddleAnswers"
}
],
"samples": [
"{answer}",
"i think it's {answer}",
"may be {answer}",
"is it {answer}"
]
}
],
"types": [
{
"name": "RiddleAnswers",
"values": [
{
"name": {
"value": "Cold"
}
},
{
"name": {
"value": "Pawns",
"synonyms": [
"chess pawns"
]
}
},
{
"name": {
"value": "Stamp",
"synonyms": [
"the stamp"
]
}
},
{
"name": {
"value": "Piano",
"synonyms": [
"the piano",
"a piano"
]
}
}
]
}
]
}
}
}
// This sample demonstrates handling intents from an Alexa skill using the Alexa Skills Kit SDK (v2).
// Please visit https://alexa.design/cookbook for additional examples on implementing slots, dialog management,
// session persistence, api calls, and more.
const Alexa = require('ask-sdk-core');
const skillData = require('skillData.js');
const persistenceAdapter = require('ask-sdk-s3-persistence-adapter');
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
async handle(handlerInput) {
const data = getLocalizedData(handlerInput.requestEnvelope.request.locale);
console.log(data);
let speakOutput = "";
const prompt = data["QUESTION"];
let persistentAttributes = await handlerInput.attributesManager.getPersistentAttributes();
console.log(persistentAttributes.FIRST_TIME);
if(persistentAttributes.FIRST_TIME === undefined){
const dataToSave = {
"FIRST_TIME": false
}
speakOutput = data["WELCOME_MESSAGE"]+ data["QUESTION"];
const attributesManager = handlerInput.attributesManager;
attributesManager.setPersistentAttributes(dataToSave);
await attributesManager.savePersistentAttributes();
} else {
speakOutput = data["RETURNING_USERS_WELCOME"] + data["QUESTION"];
}
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(prompt)
.getResponse();
}
};
function getLocalizedData(locale){
return skillData[locale];
}
const RiddleIntentHandler = {
canHandle(handlerInput) {
return (Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'RiddleIntent') ||
(Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.YesIntent') ;
},
handle(handlerInput) {
const speakOutput = 'Here is the riddle for today. ';
const data = getLocalizedData(handlerInput.requestEnvelope.request.locale);
// Homework : Find the number of the current day and get the corresponding question.
const speechOutput = speakOutput + data["QUESTIONS"][0];
const dataToSave = {
"RIGHT_ANSWER": data["ANSWERS"][0]
}
handlerInput.attributesManager.setSessionAttributes(dataToSave);
const reprompt = data["QUESTIONS"][0] + " " + data["ANSWER_MESSAGE"];
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(reprompt)
.getResponse();
}
};
const AnswerIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AnswerIntent';
},
handle(handlerInput) {
const data = getLocalizedData(handlerInput.requestEnvelope.request.locale);
const userAnswer = handlerInput.requestEnvelope.request.intent.slots.answer.resolutions.resolutionsPerAuthority[0].values[0].value.name;
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
const correctAnswer = sessionAttributes.RIGHT_ANSWER;
let speakOutput = '';
if(correctAnswer === userAnswer){
speakOutput = "Correct Answer. You get X points";
} else {
speakOutput = "Wrong Answer. You only have x chances remaining."
}
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speakOutput = 'You can say hello to me! How can I help?';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& (Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent'
|| Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const speakOutput = 'Goodbye!';
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'SessionEndedRequest';
},
handle(handlerInput) {
// Any cleanup logic goes here.
return handlerInput.responseBuilder.getResponse();
}
};
// The intent reflector is used for interaction model testing and debugging.
// It will simply repeat the intent the user said. You can create custom handlers
// for your intents by defining them above, then also adding them to the request
// handler chain below.
const IntentReflectorHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest';
},
handle(handlerInput) {
const intentName = Alexa.getIntentName(handlerInput.requestEnvelope);
const speakOutput = `You just triggered ${intentName}`;
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
// Generic error handling to capture any syntax or routing errors. If you receive an error
// stating the request handler chain is not found, you have not implemented a handler for
// the intent being invoked or included it in the skill builder below.
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`~~~~ Error handled: ${error.stack}`);
const speakOutput = `Sorry, I had trouble doing what you asked. Please try again.`;
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
// The SkillBuilder acts as the entry point for your skill, routing all request and response
// payloads to the handlers above. Make sure any new handlers or interceptors you've
// defined are included below. The order matters - they're processed top to bottom.
exports.handler = Alexa.SkillBuilders.custom()
.withPersistenceAdapter(
new persistenceAdapter.S3PersistenceAdapter({bucketName: process.env.S3_PERSISTENCE_BUCKET})
)
.addRequestHandlers(
LaunchRequestHandler,
RiddleIntentHandler,
AnswerIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler, // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
)
.addErrorHandlers(
ErrorHandler,
)
.lambda();
{
"name": "hello-world",
"version": "1.1.0",
"description": "alexa utility for quickly building skills",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Amazon Alexa",
"license": "ISC",
"dependencies": {
"ask-sdk-core": "^2.6.0",
"ask-sdk-model": "^1.18.0",
"aws-sdk": "^2.326.0",
"ask-sdk-s3-persistence-adapter": "^2.0.0"
}
}
module.exports = {
"en-IN": {
"WELCOME_MESSAGE":"Welcome to Riddle Me Today. I am going to ask you a riddle every day, and 3 chances to answer it correctly. The Less Chances you Take, the more points you win. All your points count towards our weekly leaderboard.",
"QUESTION": "Are you ready for today's riddle?",
"RETURNING_USERS_WELCOME": "Welcome back to Riddle Me Today. ",
"QUESTIONS": [
"What has many keys but can't open a single lock?",
"What can travel around the world while staying in a corner?",
"The eight of us go forth not back",
"What can you catch but never throw?"
],
"ANSWERS": [
"Piano",
"Stamp",
"Pawns",
"Cold"
]
},
"hi-IN":{
"WELCOME_MESSAGE":"पहेली का खेल मैं आपका स्वागत हैं, और धन्यवाद",
"QUESTION": "क्या आप खेलने के लिए तैय्यार हैं?",
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment