Skip to content

Instantly share code, notes, and snippets.

@muttoni
Last active June 17, 2019 11:10
Show Gist options
  • Select an option

  • Save muttoni/95327f89e0fbdf88f510d3a8d2e4900e to your computer and use it in GitHub Desktop.

Select an option

Save muttoni/95327f89e0fbdf88f510d3a8d2e4900e to your computer and use it in GitHub Desktop.
My Doctor Skill
// 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 LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Welcome to My Doctor. You can tell me you are in pain or to call you a doctor. Which will it be?';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const SignalPainIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'SignalPainIntent';
},
handle(handlerInput) {
const body_part = handlerInput.requestEnvelope.request.intent.slots.body_part.value;
const pain_level = handlerInput.requestEnvelope.request.intent.slots.pain_level.value;
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
sessionAttributes.current_state = "call_doctor";
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
const speechText = `It appears you have pain level of ${pain_level} in your ${body_part}! If you want to call a doctor, just ask me.`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt('I did not catch that. Did you need anything else?')
.getResponse();
}
};
const YesIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.YesIntent';
},
handle(handlerInput) {
let speechText = '';
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
if(sessionAttributes.current_state === "call_doctor") {
speechText = 'I am calling your doctor!'
} else {
speechText = 'You said yes, out of context.'
}
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.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 CallDoctorIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'CallDoctor';
},
handle(handlerInput) {
const speechText = 'I will call your doctor right now!';
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();
}
};
// 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,
SignalPainIntentHandler,
HelpIntentHandler,
YesIntentHandler,
CallDoctorIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
.addErrorHandlers(
ErrorHandler)
.lambda();
{
"interactionModel": {
"languageModel": {
"invocationName": "my doctor",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "SignalPainIntent",
"slots": [
{
"name": "body_part",
"type": "BODY_PARTS",
"samples": [
"I feel pain in my {body_part}",
"{body_part}"
]
},
{
"name": "pain_level",
"type": "AMAZON.NUMBER",
"samples": [
"i feel like a {pain_level} today",
"my pain level is {pain_level}",
"{pain_level}"
]
}
],
"samples": [
"i am in pain in my {body_part}",
"my level of pain is {pain_level}",
"my pain level is {pain_level}",
"i am in pain",
"ouch"
]
},
{
"name": "CallDoctor",
"slots": [],
"samples": [
"Call my doctor",
"Doctor",
"Call doctor"
]
},
{
"name": "AMAZON.YesIntent",
"samples": []
}
],
"types": [
{
"name": "BODY_PARTS",
"values": [
{
"name": {
"value": "knee"
}
},
{
"name": {
"value": "chest"
}
},
{
"name": {
"value": "ankle"
}
},
{
"name": {
"value": "wrist"
}
},
{
"name": {
"value": "shoulder"
}
},
{
"name": {
"value": "neck"
}
},
{
"name": {
"value": "head"
}
},
{
"name": {
"value": "leg"
}
},
{
"name": {
"value": "arm"
}
}
]
}
]
},
"dialog": {
"intents": [
{
"name": "SignalPainIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "body_part",
"type": "BODY_PARTS",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.53055835743.60939728220"
}
},
{
"name": "pain_level",
"type": "AMAZON.NUMBER",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.53055835743.1310994051756"
}
}
]
}
],
"delegationStrategy": "ALWAYS"
},
"prompts": [
{
"id": "Elicit.Slot.53055835743.1310994051756",
"variations": [
{
"type": "PlainText",
"value": "From one to ten, how much pain are you feeling in your {body_part}"
},
{
"type": "PlainText",
"value": "From one to ten, how much pain are you feeling?"
},
{
"type": "PlainText",
"value": "How much are you in pain from one to ten?"
},
{
"type": "PlainText",
"value": "What is your pain level from one to ten?"
}
]
},
{
"id": "Elicit.Slot.53055835743.60939728220",
"variations": [
{
"type": "PlainText",
"value": "Where?"
},
{
"type": "PlainText",
"value": "In what part of your body are you in pain?"
}
]
}
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment