Created
June 5, 2019 13:39
-
-
Save muttoni/c97b4cdfa1ed072977f0a8c114a926fc to your computer and use it in GitHub Desktop.
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. | |
| const Alexa = require('ask-sdk-core'); | |
| const persistenceAdapter = require('ask-sdk-s3-persistence-adapter'); | |
| const { | |
| getSlotValue | |
| } = require('ask-sdk-core'); | |
| const LaunchRequestHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'LaunchRequest'; | |
| }, | |
| async handle(handlerInput) { | |
| const persistentAttributes = await handlerInput.attributesManager.getPersistentAttributes(); | |
| let sessionAttributes; | |
| if(persistentAttributes) { | |
| sessionAttributes = persistentAttributes; | |
| } | |
| handlerInput.attributesManager.setSessionAttributes(sessionAttributes); | |
| const speechText = `<audio src='soundbank://soundlibrary/nature/amzn_sfx_ocean_wave_on_rocks_1x_02'/> Welcome to My Perfect Getaway. I can help you plan your perfect trip or review a past getaway. How can I help you?`; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt(speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| const PlanGetawayHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
| && handlerInput.requestEnvelope.request.intent.name === 'PlanGetaway'; | |
| }, | |
| handle(handlerInput) { | |
| const duration = handlerInput.requestEnvelope.request.intent.slots.duration.value; | |
| const location = handlerInput.requestEnvelope.request.intent.slots.location.value; | |
| const departure_time = handlerInput.requestEnvelope.request.intent.slots.departure_time.value; | |
| const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
| if(sessionAttributes && sessionAttributes.trip_count && sessionAttributes.trip_count > 0) { | |
| sessionAttributes.trip_count += 1; | |
| } else { | |
| sessionAttributes.trip_count = 1; | |
| } | |
| const duration2 = getSlotValue(handlerInput.requestEnvelope, 'duration'); | |
| console.log('duration:', duration2) | |
| const speechText = `Ok, lets find you a trip to ${location} for ${duration2} leaving ${departure_time}. Buckle up <audio src='soundbank://soundlibrary/transportation/amzn_sfx_car_click_seatbelt_01'/>, and let's go! <audio src='soundbank://soundlibrary/transportation/amzn_sfx_airplane_takeoff_whoosh_01'/>`; | |
| handlerInput.attributesManager.setSessionAttributes(sessionAttributes); | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt('add a reprompt if you want to keep the session open for the user to respond') | |
| .getResponse(); | |
| } | |
| }; | |
| const HelpIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
| && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const speechText = 'You can say hello to me! How can I help?'; | |
| 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'); | |
| }, | |
| async handle(handlerInput) { | |
| const speechText = 'Goodbye!'; | |
| const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
| handlerInput.attributesManager.setPersistentAttributes(sessionAttributes); | |
| await handlerInput.attributesManager.savePersistentAttributes(); | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .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(); | |
| } | |
| }; | |
| // 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, | |
| PlanGetawayHandler, | |
| HelpIntentHandler, | |
| CancelAndStopIntentHandler, | |
| SessionEndedRequestHandler, | |
| IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers | |
| .addErrorHandlers( | |
| ErrorHandler) | |
| .withPersistenceAdapter( | |
| new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET}) | |
| ) | |
| .lambda(); |
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
| { | |
| "interactionModel": { | |
| "languageModel": { | |
| "invocationName": "my perfect getaway", | |
| "intents": [ | |
| { | |
| "name": "AMAZON.CancelIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "AMAZON.HelpIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "AMAZON.StopIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "AMAZON.NavigateHomeIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "PlanGetaway", | |
| "slots": [ | |
| { | |
| "name": "duration", | |
| "type": "AMAZON.DURATION", | |
| "samples": [ | |
| "how about {duration}", | |
| "lets stay {duration}", | |
| "{duration}" | |
| ] | |
| }, | |
| { | |
| "name": "location", | |
| "type": "AMAZON.City", | |
| "samples": [ | |
| "let's go to {location}", | |
| "{location}" | |
| ] | |
| }, | |
| { | |
| "name": "departure_time", | |
| "type": "AMAZON.DATE", | |
| "samples": [ | |
| "{departure_time}" | |
| ] | |
| }, | |
| { | |
| "name": "theme", | |
| "type": "THEMES" | |
| } | |
| ], | |
| "samples": [ | |
| "help me plan a {theme} vacation", | |
| "plan a {theme} getaway", | |
| "i want to leave {departure_time}", | |
| "to go to {location}", | |
| "plan a trip to {location}", | |
| "i want to go to {location}", | |
| "plan a {duration} day getaway", | |
| "i am bored", | |
| "get me out of here", | |
| "find me a holiday", | |
| "i want a holiday", | |
| "plan a trip", | |
| "i want to get away" | |
| ] | |
| } | |
| ], | |
| "types": [ | |
| { | |
| "name": "THEMES", | |
| "values": [ | |
| { | |
| "name": { | |
| "value": "relaxing", | |
| "synonyms": [ | |
| "doing nothing", | |
| "recharge", | |
| "chill out", | |
| "chilled", | |
| "relax" | |
| ] | |
| } | |
| }, | |
| { | |
| "name": { | |
| "value": "adrenaline", | |
| "synonyms": [ | |
| "crazy", | |
| "exploration", | |
| "adventure" | |
| ] | |
| } | |
| }, | |
| { | |
| "name": { | |
| "value": "romantic", | |
| "synonyms": [ | |
| "honeymoon", | |
| "couples", | |
| "passionate", | |
| "love", | |
| "romance" | |
| ] | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }, | |
| "dialog": { | |
| "intents": [ | |
| { | |
| "name": "PlanGetaway", | |
| "confirmationRequired": false, | |
| "prompts": {}, | |
| "slots": [ | |
| { | |
| "name": "duration", | |
| "type": "AMAZON.DURATION", | |
| "confirmationRequired": false, | |
| "elicitationRequired": true, | |
| "prompts": { | |
| "elicitation": "Elicit.Slot.682835773707.818990482642" | |
| } | |
| }, | |
| { | |
| "name": "location", | |
| "type": "AMAZON.City", | |
| "confirmationRequired": false, | |
| "elicitationRequired": true, | |
| "prompts": { | |
| "elicitation": "Elicit.Slot.682835773707.1416995003727" | |
| } | |
| }, | |
| { | |
| "name": "departure_time", | |
| "type": "AMAZON.DATE", | |
| "confirmationRequired": false, | |
| "elicitationRequired": true, | |
| "prompts": { | |
| "elicitation": "Elicit.Slot.682835773707.1248430058630" | |
| } | |
| }, | |
| { | |
| "name": "theme", | |
| "type": "THEMES", | |
| "confirmationRequired": false, | |
| "elicitationRequired": false, | |
| "prompts": {} | |
| } | |
| ] | |
| } | |
| ], | |
| "delegationStrategy": "ALWAYS" | |
| }, | |
| "prompts": [ | |
| { | |
| "id": "Elicit.Slot.682835773707.818990482642", | |
| "variations": [ | |
| { | |
| "type": "PlainText", | |
| "value": "How long?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "How many days do you want to escape?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "How long shall the getaway be?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "How long do you want to go on vacation for?" | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "Elicit.Slot.682835773707.1416995003727", | |
| "variations": [ | |
| { | |
| "type": "PlainText", | |
| "value": "What's your destination?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "Where to?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "Where do you wanna go?" | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "Elicit.Slot.682835773707.1248430058630", | |
| "variations": [ | |
| { | |
| "type": "PlainText", | |
| "value": "When do you want to leave?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "I love {location} . When do you want to leave?" | |
| }, | |
| { | |
| "type": "PlainText", | |
| "value": "{location} it is. When do you want to leave?" | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| } |
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
| { | |
| "name": "hello-world", | |
| "version": "0.9.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": "*", | |
| "ask-sdk-s3-persistence-adapter": "*", | |
| "ask-sdk-model": "^1.4.1", | |
| "aws-sdk": "^2.326.0" | |
| } | |
| } |
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. | |
| const Alexa = require('ask-sdk-core'); | |
| const persistenceAdapter = require('ask-sdk-s3-persistence-adapter'); | |
| const { | |
| getSlotValue | |
| } = require('ask-sdk-core'); | |
| const LaunchRequestHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'LaunchRequest'; | |
| }, | |
| handle(handlerInput) { | |
| const speechText = 'Welcome, you can say Hello or Help. Which would you like to try?'; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt(speechText) | |
| .getResponse(); | |
| } | |
| }; | |
| const SwearIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
| && handlerInput.requestEnvelope.request.intent.name === 'SwearIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const phrase = getSlotValue(handlerInput.requestEnvelope, 'phrase'); | |
| const nonowords = [ | |
| 'damn', | |
| 'dang', | |
| 'heck', | |
| 'shoot', | |
| 'fudge' | |
| ]; | |
| let count = 0; | |
| nonowords.map(function(item) { | |
| const regex = RegExp(item,'g'); | |
| const match = phrase.match(regex); | |
| count += (match || []).length; | |
| }); | |
| const speechText = `You used ${count} bad words!`; | |
| const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
| if(sessionAttributes && sessionAttributes.swear_count && sessionAttributes.swear_count > 0) { | |
| sessionAttributes.swear_count += count; | |
| } else { | |
| sessionAttributes.swear_count = count; | |
| } | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .reprompt('add a reprompt if you want to keep the session open for the user to respond') | |
| .getResponse(); | |
| } | |
| }; | |
| const HelpIntentHandler = { | |
| canHandle(handlerInput) { | |
| return handlerInput.requestEnvelope.request.type === 'IntentRequest' | |
| && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent'; | |
| }, | |
| handle(handlerInput) { | |
| const speechText = 'You can say hello to me! How can I help?'; | |
| 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 speechText = 'Goodbye!'; | |
| return handlerInput.responseBuilder | |
| .speak(speechText) | |
| .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(); | |
| } | |
| }; | |
| const requestPresistenceInterceptor = { | |
| async process(handlerInput) { | |
| let persistentAttributes; | |
| if (handlerInput.requestEnvelope.session['new']) { | |
| try { | |
| persistentAttributes = await handlerInput.attributesManager.getPersistentAttributes() || {}; | |
| handlerInput.attributesManager.setSessionAttributes(persistentAttributes); | |
| } catch (e) { | |
| console.log('RequestInterceptor:: could not retrieve persistent attributes'); | |
| } | |
| } | |
| } | |
| } | |
| const responsePersistenceInterceptor = { | |
| async process(handlerInput, responseOutput) { | |
| const ses = (typeof responseOutput.shouldEndSession === "undefined" ? true : responseOutput.shouldEndSession); | |
| if (ses || handlerInput.requestEnvelope.request.type === 'SessionEndedRequest') { // skill was stopped or timed out | |
| let sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); | |
| handlerInput.attributesManager.setPersistentAttributes(sessionAttributes); | |
| await handlerInput.attributesManager.savePersistentAttributes(); | |
| } | |
| } | |
| } | |
| // 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, | |
| SwearIntentHandler, | |
| HelpIntentHandler, | |
| CancelAndStopIntentHandler, | |
| SessionEndedRequestHandler, | |
| IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers | |
| .addRequestInterceptors(requestPresistenceInterceptor) | |
| .addResponseInterceptors(responsePersistenceInterceptor) | |
| .addErrorHandlers( | |
| ErrorHandler) | |
| .withPersistenceAdapter( | |
| new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET}) | |
| ) | |
| .lambda(); |
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
| { | |
| "interactionModel": { | |
| "languageModel": { | |
| "invocationName": "swear buddy", | |
| "intents": [ | |
| { | |
| "name": "AMAZON.CancelIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "AMAZON.HelpIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "AMAZON.StopIntent", | |
| "samples": [] | |
| }, | |
| { | |
| "name": "SwearIntent", | |
| "slots": [ | |
| { | |
| "name": "phrase", | |
| "type": "AMAZON.SearchQuery" | |
| } | |
| ], | |
| "samples": [ | |
| "to {phrase}", | |
| "that {phrase}" | |
| ] | |
| }, | |
| { | |
| "name": "AMAZON.NavigateHomeIntent", | |
| "samples": [] | |
| } | |
| ], | |
| "types": [] | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment