обрабатывать запуск другого намерения в Алексе без завершения первого намерения - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть два намерения (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.

это работает нормально, но если пользователь запускает HelloWorldIntent в промежутке между PlaceOrderIntent, то он срабатывает, как избежать этого

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();
  }
};

1 Ответ

0 голосов
/ 13 апреля 2020

Звучит так, будто вы хотите конечный автомат.

Вот, например, ...

  • Установите state = started sessionVariable при вводе шага, который вы хотите заблокировать. то есть StartedInProgress
handlerInput.attributesManager.setSessionAttributes({state: "started"});
  • Теперь вы только "unset" state в ваших OrderFood намерениях.
handlerInput.attributesManager.setSessionAttributes({state: ""});
  • Наконец, если вы сначала зарегистрируете StartedInProcess… (ищите addRequestHandlers в вашем файле index.js) и установите для этого намерения 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 - что я очень рекомендую.

...