如果没有先调用另一个意图,如何防止意图触发

how to prevent an intent trigger if another intent has not been called first

我只想在之前触发 RandomLetterIntentHandler 时触发我的 WaitAnswerIntentHandler。 目前我的第二个意图可以用 {animal}{country}{color}{food} 话语触发(不是所有必需的并且可以按任何顺序)但它需要第一个意图来制作我想要的逻辑。

const RandomLetterIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'RandomLetterIntent';
    },
    handle(handlerInput) {
  // **get a letter from the user**
        const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
        const randomLetter = randomLetterGenerator.getOneRandomLetter();
        const speechText = requestAttributes.t('RANDOM_LETTER_ASK', randomLetter);
        timerUtils.startTimer();
        puntuacion = 0;
        letter= randomLetter;
        return handlerInput.responseBuilder
            .speak(speechText)
            .reprompt(speechText)
            .getResponse();
    }
};
const WaitAnswerIntentHandler = {
    canHandle(handlerInput){
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
        && Alexa.getIntentName(handlerInput.requestEnvelope) === 'WaitAnswerIntent'
        && gameState > 0;
    },
    handle(handlerInput){
### **// get {animal}{country}{color}{food} (not all required and can be in any order) but need the letter that is obtained in the previous intent**
        const intent = handlerInput.requestEnvelope.request.intent;

        const animal = intent.slots.ANIMAL.value;
        const country = intent.slots.COUNTRY.value;
        const color = intent.slots.COLOR.value;
        const food = intent.slots.FOOD.value;

        let cadenaFinal = '';
        let tiempoFinal = 0;

        if(animal && animal[0]===letter){
            puntuacion = puntuacion + 10;
            cadenaFinal = cadenaFinal + ' ' + animal;
        }
        if(country && country[0]===letter){
            puntuacion = puntuacion + 10;
            cadenaFinal = cadenaFinal + ' ' + country;
        }
        if(color && color[0]===letter){
            puntuacion = puntuacion + 10;
            cadenaFinal = cadenaFinal + ' ' + color;
        }
        if(food && food[0]===letter){
            puntuacion = puntuacion + 10;
            cadenaFinal = cadenaFinal + ' ' + food;
        }

        tiempoFinal = timerUtils.endTimer();
        puntuacion = puntuacion - tiempoFinal;

        if(!cadenaFinal){cadenaFinal='ninguna'}
        const repromtText = 'pídeme otra letra para seguir jugando';
        const speakOutput = `Tu respuesta válida fue ${cadenaFinal}, has tardado ${tiempoFinal.toString()} segundos y tu puntuación es ${puntuacion.toString()}`;
        gameState = 0;
        return handlerInput.responseBuilder
        .speak(speakOutput)
        .reprompt(repromtText)
        .getResponse();
    }
};

您可以添加一个名为 state 的新会话属性,并在您的 canHandle 函数中对其进行验证。

在您的情况下,在处理 RandomLetterIntentHandler 之后,您可以将 state 设置为 answer 或您认为最适合它的任何名称,然后在 WaitAnswerIntentHandler canHandle 函数检查 state 是否为 answer。如果是,则处理请求并将 state 设置为默认值或将其删除。这样 WaitAnswerIntentHandler 只会在 RandomLetterIntentHandler.

之后调用

更具体的示例可以在 alexa sdk repo 'High Low' 游戏中找到。

这是来自亚马逊官方开发人员的最佳解决方案。

const Alexa = require('ask-sdk-core');
let hello = false;

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const speechText = 'Welcome to the Alexa Skills Kit, you can say hello!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
  },
};

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  handle(handlerInput) {
    hello = true;
    const speechText = `Hello`;
    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
  },
};

const ByeIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'ByeIntent';
  },
  handle(handlerInput) {
    let speechText;
    if (!hello) {
      speechText = 'dont say bye before hello';
      return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
    }
    speechText = `Bye`;
    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
  },
};

const ErrorHandler = {
  canHandle(handlerInput, error) {
    return true;
  },
  handle(handlerInput, error) {

      return handlerInput.responseBuilder
      .speak('I do not understand what you say')
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
    hello = false;
    return handlerInput.responseBuilder.getResponse();
  },
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    HelloWorldIntentHandler,
    ByeIntentHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();