我有一个NewContactIntent,用户可以在其中输入姓名和手机号码等数据。我希望他能够在任何时候重新启动对话框。因此,我有一个RestartIntent,所以当用户说"重新启动"时,RestartIntentHandler会处理该请求,并将其转发回NewContactIntent。这是代码:
const NewContactIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'NewContactIntent';
},
handle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
const currentIntent = handlerInput.requestEnvelope.request.intent;
if (request.dialogState !== 'COMPLETED') {
return handlerInput.responseBuilder
.addDelegateDirective(currentIntent)
.getResponse();
} else {
const speechText = 'Kontakt hinzugefügt.';
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
}
};
const RestartIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& (handlerInput.requestEnvelope.request.intent.name === 'RestartIntent');
},
handle(handlerInput) {
return NewContactIntentHandler.handle(handlerInput);
}
};
它不起作用,当我尝试它时,alexa会显示来自ErrorHandler的错误消息。
编辑
这个例子有效,BarHandler调用FooHandler,所以我不明白为什么我的案例不起作用:
const FooIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'FooIntent';
},
handle(handlerInput) {
const speechText = 'Ich bin FooIntent!';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const BarIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'BarIntent';
},
handle(handlerInput) {
return FooIntentHandler.handle(handlerInput);
}
};
添加"重新启动"话语
如果您只有一个意图,则可以添加"restart">或《reset》作为话语,并从头开始对话框。
问题:但如果您还有两个意图要重新设置,则话语"重置">将触发其中任何一个。即使您处于IntentA
的中间,然后说"重置">,也可能触发同样具有‘重置’话语的IntentB
。
添加RestartIntent
添加带有"reset">或《restart》等语句的RestartIntent
肯定会触发RestartIntent
,并且在lastDialogIntent
等sessionAttribute
的帮助下,将帮助您了解要重新启动哪个对话框。
问题:对话框模型的问题是,您无法引出与当前意图不同的意图。这意味着,当您说"重新启动">时,Alexa将触发RestartIntent
,并且您不能用想要重新设定种子的Dialog Directive
进行响应。
请注意,返回Dialog指令时不能更改意图,因此,意向名称和插槽集必须与发送到技巧
棘手的部分是,用户必须从RestartIntent中再次说出触发所需意图的内容,比如IntentA
。
Ex:
User: I want to buy a car [triggered BuyCarIntent]
Alexa: Which color do you want? [first slot to be filled]
User: I want yellow color. [First slot filled]
Alexa: Which is your preferred make?
User: restart [triggred RestartIntent]
Alexa: okay, what color do you want? [make the user respond in such a way that the user
speech will trigger the required intent again.]
User: I want yellow color. [triggered BuyCarIntent]
如果用户只说"黄色">,有时可能不会触发意图,这取决于交互模型的设计。调整你的互动模型,并添加可以帮助你做到这一点的话语。
以这样一种方式回应,即用户会说一些会再次触发意图的话使用sessionAttribute
来存储和检索上次使用的对话意图,例如:"lastDialogIntent":"BuyCarIntent"
,以回答与意图匹配的适当问题。
一旦重新触发,对话框模型将从头开始。
我能想到两种可能的解决方案:1(在NewContactIntent中添加诸如">restart"、">重新启动"之类的语句,当用户说重新启动时,对话框将自动从头开始。2(添加另一个重新启动意图,但不要在NewContactIntent的canHandle函数中编写单独的处理程序
const NewContactIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& (handlerInput.requestEnvelope.request.intent.name === 'NewContactIntent'
||handlerInput.requestEnvelope.request.intent.name === 'RestartIntent')
},
注意:如果您希望重新启动对话框仅在NewContactIntent对话框启动后工作,则可以通过在NewContactIntent中将会话属性状态设置为">dialogStarted",然后更新NewContactIntent如下所示:
const NewContactIntentHandler = {
canHandle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& ((handlerInput.requestEnvelope.request.intent.name === 'NewContactIntent')
||(handlerInput.requestEnvelope.request.intent.name === 'RestartIntent'
&& sessionAttributes.state === 'dialogStarted'))