如何在Alexa Skill中重新启动对话框



我有一个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,并且在lastDialogIntentsessionAttribute的帮助下,将帮助您了解要重新启动哪个对话框。

问题:对话框模型的问题是,您无法引出与当前意图不同的意图。这意味着,当您说"重新启动">时,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(添加另一个重新启动意图,但不要在NewContactIntentcanHandle函数中编写单独的处理程序

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'))

最新更新