Created
September 2, 2019 21:09
-
-
Save anoop4real/581af0c4cee8f48921a7dd4752a1dbae to your computer and use it in GitHub Desktop.
A demo sample for session attributes of Alexa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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.var | |
| const Alexa = require('ask-sdk-core'); | |
| const SKILL_NAME = "Number"; | |
| const ANSWER_THIS_MESSAGE = "Answer this : "; | |
| const HELP_MESSAGE = 'What can I help you with?'; | |
| const HELP_REPROMPT = 'What can I help you with?'; | |
| const STOP_MESSAGE = 'Enjoy the day...Goodbye!'; | |
| const SKIP_MESSAGE = 'Ok, here is another one,'; | |
| const CORRECT_ANSWER_MESSAGE = 'Correct Answer!!'; | |
| const WRONG_ANSWER_MESSAGE = 'Oops, Wrong anwser!!'; | |
| const MORE_MESSAGE = 'Do you want another one?'; | |
| const ERROR_MESSAGE = 'Oops, Something went wrong, please try later!!'; | |
| const PAUSE = '<break time="0.3s" />'; | |
| const WHISPER = '<amazon:effect name="whispered"/>'; | |
| const FALLBACK_REPROMPT = 'shall I fetch you one?'; | |
| const FALLBACK = SKILL_NAME + 'skill cant help with that, but I can help you with finding a QUESTION: for you to guess.' + PAUSE + FALLBACK_REPROMPT; | |
| const FALLBACK_MESSAGE_DURING_GAME = `The ${SKILL_NAME} skill can't help you with that. Try answering the question. `; | |
| const FALLBACK_REPROMPT_DURING_GAME = 'Try answering the question.'; | |
| var gameStates = { | |
| started: 'started', | |
| waiting: 'waiting', | |
| ended: 'ended' | |
| }; | |
| var currentState = gameStates.started; | |
| const LaunchRequestHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'LaunchRequest'; | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = getAQuestion(); | |
| saveCurrentStateWith(handlerInput); | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } | |
| }; | |
| const SkipTheQuestionIntentHandler = { | |
| canHandle(handlerInput) { | |
| var isWaitingForAnswer = true; | |
| const state = fetchCurrentSavedState(handlerInput); | |
| if (state !== gameStates.waiting) { | |
| isWaitingForAnswer = false; | |
| } | |
| return isWaitingForAnswer && handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'SkipTheQuestion'; | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = getAQuestion(); | |
| saveCurrentStateWith(handlerInput); | |
| return handlerInput.responseBuilder | |
| .speak(SKIP_MESSAGE + speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } | |
| }; | |
| const GuessTheAnswerIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'GuessTheAnswer'; | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = getAQuestion(); | |
| saveCurrentStateWith(handlerInput); | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } | |
| }; | |
| const AnswerIntentHandler = { | |
| canHandle(handlerInput) { | |
| var isWaitingForAnswer = true; | |
| const state = fetchCurrentSavedState(handlerInput); | |
| if (state !== gameStates.waiting) { | |
| isWaitingForAnswer = false; | |
| } | |
| return isWaitingForAnswer && handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'AnswerIntent'; | |
| }, | |
| handle(handlerInput) { | |
| var answer = handlerInput.requestEnvelope.request.intent.slots.answer.value; | |
| var lowerAnswer = answer.toLowerCase() | |
| const speechObj = validateAnswerAndPrepareResponse(lowerAnswer); | |
| saveCurrentStateWith(handlerInput); | |
| if (speechObj.reprompt) { | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } else { | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .getResponse(); | |
| } | |
| } | |
| }; | |
| const HelpIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const speechText = HELP_MESSAGE; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt(speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| const CancelAndStopIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent' || | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent'); | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = stopAndExit(); | |
| saveCurrentStateWith(handlerInput) | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| const YesIntentHandler = { | |
| canHandle(handlerInput) { | |
| var isWaitingForAnswer = true; | |
| const state = fetchCurrentSavedState(handlerInput); | |
| if (state !== gameStates.waiting) { | |
| isWaitingForAnswer = false; | |
| } | |
| return !isWaitingForAnswer && handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.YesIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = getAQuestion(); | |
| saveCurrentStateWith(handlerInput) | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } | |
| }; | |
| const NoIntentHandler = { | |
| canHandle(handlerInput) { | |
| var isWaitingForAnswer = true; | |
| const state = fetchCurrentSavedState(handlerInput); | |
| if (state !== gameStates.waiting) { | |
| isWaitingForAnswer = false; | |
| } | |
| return !isWaitingForAnswer && handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.NoIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const speechObj = stopAndExit(); | |
| saveCurrentStateWith(handlerInput) | |
| return handlerInput.responseBuilder | |
| .withShouldEndSession(true) | |
| .speak(speechObj.speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| const FallbackIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' && | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.FallbackIntent' || | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.YesIntent' || | |
| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.NoIntent' || | |
| handlerInput.requestEnvelope.request.intent.name === 'SkipTheQuestion' || | |
| handlerInput.requestEnvelope.request.intent.name === 'AnswerIntent'; | |
| }, | |
| handle(handlerInput) { | |
| var isWaitingForAnswer = true; | |
| const state = fetchCurrentSavedState(handlerInput); | |
| const speechObj = fallback(state); | |
| return handlerInput.responseBuilder | |
| .speak(speechObj.speechText) | |
| .reprompt(speechObj.reprompt) | |
| .getResponse(); | |
| } | |
| }; | |
| const SessionEndedRequestHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === '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 handlerInput.requestEnvelope.request.type === 'IntentRequest'; | |
| }, | |
| handle(handlerInput) { | |
| const intentName = handlerInput.requestEnvelope.request.intent.name; | |
| const speechText = `You just triggered ${intentName}`; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| //.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.message}`); | |
| const speechText = `Sorry, I couldn't understand what you said. Please try again.`; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt(speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| function getAQuestion() { | |
| var welcomeSpeechOutput = `Welcome to ${SKILL_NAME} <break time="0.3s" />`; | |
| const topic = prepareAQuestion(); | |
| const tempOutput = WHISPER + ANSWER_THIS_MESSAGE + topic + PAUSE; | |
| const speechOutput = welcomeSpeechOutput + tempOutput; | |
| const more = ANSWER_THIS_MESSAGE; | |
| currentState = gameStates.waiting; | |
| var jsonObj = { | |
| speechText: speechOutput, | |
| reprompt: more, | |
| topic: topic | |
| }; | |
| return jsonObj | |
| } | |
| function validateAnswerAndPrepareResponse(answer) { | |
| var responseText = ''; | |
| var more = MORE_MESSAGE; | |
| var jsonObj; | |
| if (answer) { | |
| // If the answer given by the user falls in any of the possible answers then return true | |
| responseText += CORRECT_ANSWER_MESSAGE; | |
| responseText += MORE_MESSAGE; | |
| jsonObj = { | |
| speechText: responseText, | |
| reprompt: more | |
| }; | |
| } else { | |
| responseText += ERROR_MESSAGE; | |
| jsonObj = { | |
| speechText: responseText | |
| }; | |
| } | |
| currentState = gameStates.ended; | |
| return jsonObj | |
| } | |
| function saveCurrentStateWith(handlerInput) { | |
| const attributesManager = handlerInput.attributesManager; | |
| const sessionAttributes = attributesManager.getSessionAttributes(); | |
| sessionAttributes.gameState = currentState; | |
| } | |
| function fetchCurrentSavedState(handlerInput) { | |
| const attributesManager = handlerInput.attributesManager; | |
| const sessionAttributes = attributesManager.getSessionAttributes(); | |
| if (sessionAttributes.gameState) { | |
| currentState = sessionAttributes.gameState | |
| return currentState | |
| } else { | |
| sessionAttributes.gameState = currentState; | |
| return currentState | |
| } | |
| } | |
| function prepareAQuestion() { | |
| const randomQuestion = 'What is the answer of 9 + 9' | |
| return randomQuestion + PAUSE + randomQuestion | |
| } | |
| function stopAndExit() { | |
| const speechOutput = STOP_MESSAGE; | |
| currentState = gameStates.ended; | |
| var jsonObj = { | |
| speechText: speechOutput | |
| }; | |
| return jsonObj; | |
| } | |
| function fallback(state) { | |
| var speechOutput = FALLBACK; | |
| var reprompt = FALLBACK_REPROMPT; | |
| if (state === gameStates.waiting) { | |
| speechOutput = FALLBACK_MESSAGE_DURING_GAME; | |
| reprompt = FALLBACK_REPROMPT_DURING_GAME; | |
| } | |
| var jsonObj = { | |
| speechText: speechOutput, | |
| reprompt: reprompt | |
| }; | |
| return jsonObj; | |
| } | |
| function help() { | |
| const speechOutput = HELP_MESSAGE; | |
| const reprompt = HELP_REPROMPT; | |
| var jsonObj = { | |
| speechText: speechOutput, | |
| reprompt: reprompt | |
| }; | |
| return jsonObj; | |
| } | |
| // This handler 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() | |
| .addRequestHandlers( | |
| LaunchRequestHandler, | |
| GuessTheAnswerIntentHandler, | |
| SkipTheQuestionIntentHandler, | |
| AnswerIntentHandler, | |
| YesIntentHandler, | |
| NoIntentHandler, | |
| HelpIntentHandler, | |
| FallbackIntentHandler, | |
| HelpIntentHandler, | |
| CancelAndStopIntentHandler, | |
| SessionEndedRequestHandler, | |
| IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers | |
| .addErrorHandlers( | |
| ErrorHandler) | |
| .lambda(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment