我有两个意图(HelloWorldIntent和PlaceOrderIntent),第一个意图是关于hello world,第二个意图是下订单(为此我需要填写广告位)
user: open demo bot
Alexa: welcome!
user: place order
alexa: you can order platter, soup, and shake?
user: soup
alexa: which type of soup? tomato, onion or corn?
user: tomato
alexa: your order for tomato soup has been placed.
这很好,但是如果用户在PlaceOrderIntent之间触发HelloWorldIntent,那么它将被触发,如何避免这种情况
user: open demo bot
alexa: welcome!
user: place order
alexa: you can order platter, soup and shake?
user : hello
alexa: hello world!
没有完成PlaceOrderIntent,就会触发另一个意图,而不是显示提示消息。
这是我的代码
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
},
handle(handlerInput) {
const speakOutput = 'Hello World!';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt()
.getResponse();
}
};
const StartedInProgressOrderFoodIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.dialogState !== 'COMPLETED'
&& !handlerInput.requestEnvelope.request.intent.slots.menu.value;
},
handle(handlerInput) {
const speakOutput = `You can order Platters, Soups and, Shakes. What you want to order?`
const prompt = `Please select any one from platter, soup or, drink.`
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(prompt)
.addElicitSlotDirective('menu')
.getResponse();
}
};
const PlatterGivenOrderFoodIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.intent.slots.menu.value
&& handlerInput.requestEnvelope.request.intent.slots.menu.value === 'platter'
&& !handlerInput.requestEnvelope.request.intent.slots.platType.value;
},
handle(handlerInput) {
const speakOutput = `Which platter would you like Regular, Special, Rajasthani, Gujarati, or Punjabi?`
const prompt = `Which platter would you like Regular, Special, Rajasthani, Gujarati, or Punjabi?`
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(prompt)
.addElicitSlotDirective('platType')
.getResponse();
}
};
const SoupGivenOrderFoodIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.intent.slots.menu.value
&& handlerInput.requestEnvelope.request.intent.slots.menu.value === 'soup'
&& !handlerInput.requestEnvelope.request.intent.slots.soupType.value;
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak("Which soup would you like tomato, manchow, onion, or corn soup?")
.reprompt("Would you like a tomato, manchow, onion, or corn soup?")
.addElicitSlotDirective('soupType')
.getResponse();
}
};
const ShakeGivenOrderFoodIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.intent.slots.menu.value
&& handlerInput.requestEnvelope.request.intent.slots.menu.value === 'shake'
&& !handlerInput.requestEnvelope.request.intent.slots.shakeType.value;
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak("Which shake would you like chocolate, vanilla, milk, strawberry, or mango shake?")
.reprompt("Would you like a chocolate, vanilla, milk, strawberry, or mango shake?")
.addElicitSlotDirective('shakeType')
.getResponse();
}
};
const CompletedOrderFoodIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.dialogState === "COMPLETED"
&& handlerInput.requestEnvelope.request.intent.slots.menu.value
|| handlerInput.requestEnvelope.request.intent.slots.platType.value || handlerInput.requestEnvelope.request.intent.slots.soupType.value || handlerInput.requestEnvelope.request.intent.slots.shakeType.value;
},
handle(handlerInput){
const menuitems = handlerInput.requestEnvelope.request.intent.slots.menu.value;
let type;
if (menuitems === 'platter') {
type = handlerInput.requestEnvelope.request.intent.slots.platType.value;
} else if (menuitems === 'soup') {
type = handlerInput.requestEnvelope.request.intent.slots.soupType.value;
} else if (menuitems === 'shake') {
type = handlerInput.requestEnvelope.request.intent.slots.shakeType.value;
} else {
type = 'water'
}
const speechText = `Your order for ${type} ${menuitems} has been placed.`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt()
.getResponse();
}
};
听起来像您想要状态机。
例如,这里...
state = started
sessionVariable在输入您要锁定的步骤时。 即StartedInProgresshandlerInput.attributesManager.setSessionAttributes({state: "started"});
state
意向“取消设置” OrderFood
。handlerInput.attributesManager.setSessionAttributes({state: ""});
StartedInProcess…
(在addRequestHandlers
文件中搜索index.js
),并将该意图的canHandle
设置为包括“状态为start而不是OrderFood意图之一”,它将始终如果您处于该状态但不尝试订购,则开除。const StartedInProgressOrderFoodIntentHandler = {
canHandle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
hasStarted = sessionAttributes.state == "started"
isOrdering = handlerInput.requestEnvelope.request.intent.name.includes('GivenOrder')
return (hasStarted and !isOrdering) or (
handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.intent.name === "PlaceOrderIntent"
&& handlerInput.requestEnvelope.request.dialogState !== 'COMPLETED'
&& !handlerInput.requestEnvelope.request.intent.slots.menu.value);
}
…
意识到这意味着您的用户将被锁定在该过程中……除非您在可以清除StartedInProcess
的state
之前注册另一个意图(例如,退出吗?),我强烈建议这样做。