如何在Alexa Skill

时间:2018-11-06 16:26:00

标签: javascript node.js alexa alexa-skills-kit alexa-skill

我有一个NewContactIntent,用户可以在其中输入诸如名字和手机号码等数据。我希望他能够在任何时候重新启动对话框。因此,我有一个RestartIntent,因此当用户说“ Restart”时,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);
    }
};

2 个答案:

答案 0 :(得分:2)

添加“重启”语音

如果您只有一个意图,则可以添加“重启” “重置” 作为话语,并从头开始对话。

问题:但是,如果您还有两个要重置的意图,则发话“重置” 会触发其中的任何一个。即使您处于IntentA的中间,然后说出“重置” ,它也可能会触发IntentB的人也说出“重置”

添加RestartIntent

添加带有{strong>“重置” 或“重启” 之类的语音提示的RestartIntent肯定会触发RestartIntent并借助{{ 1}}(如sessionAttribute可以帮助您了解要重新启动哪个对话框。

问题:对话框模型的问题在于,您无法引发与当前意图不同意图的插槽。这意味着当您说“重新启动” 时,Alexa将触发lastDialogIntent,并且您无法用RestartIntent的重置意图来回应。

  

请注意,返回Dialog指令时不能更改意图,   因此,意图名称和插槽组必须匹配发送给您​​的意图   技能。

棘手的部分是,用户必须说出会触发所需意图的内容,例如Dialog Directive

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] 存储和检索上次使用的对话意图,例如:{ {1}}回答与意图相符的适当问题。

重新触发后,对话框模型将从头开始。

答案 1 :(得分:1)

我能想到的有两个解决方案: 1) NewContactIntent 中添加诸如“ 重新启动”,“ 重新开始”之类的语音提示,并在用户说重启时,对话框将自动从头开始。 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 ”,然后更新 canHandle 功能的 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'))