【问题标题】:handle triggering of another intent in alexa without completing first intent在没有完成第一个意图的情况下处理在 alexa 中触发另一个意图
【发布时间】:2020-07-25 14:36:54
【问题描述】:

我有两个意图(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();
  }
};

【问题讨论】:

    标签: chatbot alexa alexa-skill alexa-voice-service alexa-slot


    【解决方案1】:

    听起来你想要一个状态机。

    这是一个例子...

    • 在进入要锁定的步骤时设置state = started sessionVariable。 即,StartedInProgress
    handlerInput.attributesManager.setSessionAttributes({state: "started"});
    
    • 现在您只能在您的 OrderFood 意图中“取消设置”state
    handlerInput.attributesManager.setSessionAttributes({state: ""});
    
    • 最后,如果您首先注册StartedInProcess…(在您的index.js 文件中搜索addRequestHandlers),并将该意图的canHandle 设置为包含“状态是开始而不是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 的意图(例如,退出?)——我强烈建议这样做。

    【讨论】:

    • 感谢@Timothy Aaron 的帮助,但我是新手,所以请您告诉我按照您的步骤操作后代码应该是什么样子。
    • 我试过了。我使用 Python SDK,所以缺乏我的 JS(更不用说 Alexa NodeJS SDK)技能……但这至少应该为您提供足够的细节来完成大部分工作。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多