Alexa中另一个意图的句柄触发未完成第一个意图

问题描述 投票:0回答:1

我有两个意图(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个回答
0
投票

听起来像您想要状态机。

例如,这里...

  • 设置state = started sessionVariable在输入您要锁定的步骤时。 即StartedInProgress
handlerInput.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);
    }
  …

意识到这意味着您的用户将被锁定在该过程中……除非您在可以清除StartedInProcessstate之前注册另一个意图(例如,退出吗?),我强烈建议这样做。

© www.soinside.com 2019 - 2024. All rights reserved.