I'm trying to create an alexa skill with the help of 'Survey' template, which uses personalization + voice recognition based auth.
personalization + voice recognition based auth works fine. I have added a new intent 'Introduce' which needs to be triggered based on utterance - 'introduce' but that isn't working as expected.
- Alexa open my bot -> (welcome note from alexa)
- let's begin (invokes StartMyStandupIntentHandler intent and auth based on voice id) -> Hello How can i help you?
- introduce -> doesn't invoke IntroduceHandler but i have IntentReflectorHandler that says : You just triggered the introduce intent. You're hearing this response because introduce does not have an intent handler yet.
index.js:
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
const skillName = requestAttributes.t('SKILL_NAME');
const name = personalization.getPersonalizedPrompt(handlerInput);
var speakOutput = ""
if (name && name.length > 0) {
speakOutput = requestAttributes.t('GREETING_PERSONALIZED', skillName);
} else {
speakOutput = requestAttributes.t('GREETING', skillName);
}
const repromptOutput = requestAttributes.t('GREETING_REPROMPT');
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(repromptOutput)
.getResponse();
},
};
const StartMyStandupIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'StartMyStandupIntent';
},
async handle(handlerInput) {
const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
let speakOutput;
const name = personalization.getPersonalizedPrompt(handlerInput);
let response = handlerInput.responseBuilder;
if (name && name.length > 0) {
speakOutput = 'Hello '+ name +'! How can i help you?';
const upsServiceClient = handlerInput.serviceClientFactory.getUpsServiceClient();
let profileName
let profileEmail
try {
profileName = await upsServiceClient.getPersonsProfileGivenName();
profileEmail = await upsServiceClient.getProfileEmail();
} catch (error) {
return handleError(error, handlerInput)
}
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
sessionAttributes.userEmail = profileEmail;
sessionAttributes.userName = profileName;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
} else {
speakOutput = requestAttributes.t('PERSONALIZED_FALLBACK')
}
return response
.speak(speakOutput)
.withShouldEndSession(false)
.getResponse()
},
};
const Introduce_Handler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'Introduce'
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
let say = 'Hi everyone, As the famous saying goes, \'The human voice is the most perfect instrument of all\', . ';
say += 'A very Warm greetings to all. ';
return responseBuilder
.speak(say)
.withShouldEndSession(false)
.getResponse();
},
};
/**
* Voice consent request - response is handled via Skill Connections.
* Hence we need to handle async response from the Voice Consent.
* The user could have accepted or rejected or skipped the voice consent request.
* Create your custom callBackFunction to handle accepted flow - in this case its handling identifying the person
* The rejected/skipped default handling is taken care by the library.
*
* @params handlerInput - the handlerInput received from the IntentRequest
* @returns
**/
async function handleCallBackForVoiceConsentAccepted(handlerInput) {
const upsServiceClient = handlerInput.serviceClientFactory.getUpsServiceClient();
let profileName = await upsServiceClient.getProfileEmail();
let profileEmail = await upsServiceClient.getPersonsProfileGivenName();
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
sessionAttributes.userEmail = profileEmail;
sessionAttributes.userName = profileName;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
// this is done because currently intent chaining is not supported from any
// Skill Connections requests, such as SessionResumedRequest.
const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
const name = personalization.getPersonalizedPrompt(handlerInput);
let speakOutput = 'Hello '+ name +'! How can i help you?';
//let repromptOutput = requestAttributes.t('ABOUT_REPROMPT');
let response = handlerInput.responseBuilder;
return response
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse()
}
Interaction model json:
{
"interactionModel": {
"languageModel": {
"invocationName": "my bot",
"modelConfiguration": {
"fallbackIntentSensitivity": {
"level": "LOW"
}
},
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "GetCodeIntent",
"slots": [
{
"name": "MeetingCode",
"type": "AMAZON.NUMBER"
}
],
"samples": [
"My code is {MeetingCode}",
"The code is {MeetingCode}",
"{MeetingCode}"
]
},
{
"name": "GetReportIntent",
"slots": [
{
"name": "questionYesterday",
"type": "AMAZON.SearchQuery",
"samples": [
"{questionYesterday}"
]
},
{
"name": "questionToday",
"type": "AMAZON.SearchQuery",
"samples": [
"{questionToday}"
]
},
{
"name": "questionBlocking",
"type": "AMAZON.SearchQuery",
"samples": [
"{questionBlocking}"
]
}
],
"samples": [
"{questionToday} today",
"{questionYesterday} yesterday",
"yesterday {questionYesterday}",
"today {questionToday}"
]
},
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.YesIntent",
"samples": []
},
{
"name": "AMAZON.NoIntent",
"samples": []
},
{
"name": "ResetPinIntent",
"slots": [],
"samples": [
"where do i get a pin",
"what is my pin",
"how do i get a pin",
"i need a new pin",
"i forgot my pin"
]
},
{
"name": "StartMyStandupIntent",
"slots": [],
"samples": [
"yes let's get started",
"yes let's begin",
"let's begin",
"let's get started"
]
},
{
"name": "Introduce",
"slots": [],
"samples": [
"introduce yourself",
"introduce",
"intro"
]
}
],
"types": []
},
"dialog": {
"intents": [
{
"name": "GetReportIntent",
"delegationStrategy": "ALWAYS",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "questionYesterday",
"type": "AMAZON.SearchQuery",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.420907304064.1434077833163"
}
},
{
"name": "questionToday",
"type": "AMAZON.SearchQuery",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.173201382582.539843571833"
}
},
{
"name": "questionBlocking",
"type": "AMAZON.SearchQuery",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.173201382582.1204298947985"
}
}
]
}
],
"delegationStrategy": "ALWAYS"
},
"prompts": [
{
"id": "Elicit.Slot.288779318596.409557698368",
"variations": [
{
"type": "PlainText",
"value": "Alright, first question. What did you do yesterday?"
}
]
},
{
"id": "Elicit.Slot.288779318596.1420775370020",
"variations": [
{
"type": "PlainText",
"value": "Got it. What will you do today?"
}
]
},
{
"id": "Elicit.Slot.288779318596.88143460540",
"variations": [
{
"type": "PlainText",
"value": "Okay, last question. Is there anything blocking your progress?"
}
]
},
{
"id": "Elicit.Slot.420907304064.1434077833163",
"variations": [
{
"type": "PlainText",
"value": "What did you work on yesterday?"
}
]
},
{
"id": "Elicit.Slot.173201382582.539843571833",
"variations": [
{
"type": "PlainText",
"value": "What will you work on today?"
}
]
},
{
"id": "Elicit.Slot.173201382582.1204298947985",
"variations": [
{
"type": "PlainText",
"value": "What if anything is blocking your progress?"
}
]
}
]
}
}