Очистить все значения слотов в намерении

У меня есть навык Алекса, в котором у меня несколько намерений. Эти намерения вызываются с использованием настраиваемых значений слотов, которые в большинстве случаев принимают ответы да / нет. Дело в том, что следующие значения слота да / нет продолжают ссылаться на последнее намерение и, следовательно, никогда не проходят мимо первого намерения. Есть ли способ сбросить значения слотов? Любая помощь приветствуется.

{
"interactionModel": {
        "languageModel": {
            "invocationName": "tata nexon test drive",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "TATANexonmodelvariantfeatureIntent",
                    "slots": [
                        {
                            "name": "modelTATANexon",
                            "type": "modeltype",
                            "samples": [
                                "i'd like to know about the {modelTATANexon} model",
                                "{modelTATANexon}"
                            ]
                        },
                        {
                            "name": "variantTATANexon",
                            "type": "varianttype",
                            "samples": [
                                "i'd like to know about the {variantTATANexon} variant",
                                "{variantTATANexon}"
                            ]
                        }
                    ],
                    "samples": [
                        "TATA Nexon Test Drive",
                        "start test drive",
                        "start TATA Nexon Test Drive",
                        "launch test drive",
                        "launch TATA Nexon Test Drive",
                        "load test drive",
                        "load TATA Nexon Test Drive",
                        "begin test drive",
                        "begin TATA Nexon Test Drive",
                        "enable test drive",
                        "enable TATA Nexon Test Drive"
                    ]
                },
                {
                    "name": "TATANexonmodefeatureIntent",
                    "slots": [
                        {
                            "name": "yesnomodeslot",
                            "type": "yesnomodeslottype"
                        }
                    ],
                    "samples": [
                        "i am interested",
                        "sure",
                        "nah",
                        "yeah",
                        "I am not interested",
                        "nope",
                        "yup",
                        "no",
                        "yes"
                    ]
                },
                {
                    "name": "TATANexoninfotainmentfeatureIntent",
                    "slots": [
                        {
                            "name": "yesnoinfotainmentslot",
                            "type": "yesnoinfotainmentslottype"
                        }
                    ],
                    "samples": [
                        "sure",
                        "nah",
                        "yeah",
                        "nope",
                        "yup",
                        "i am not interested",
                        "i am interested",
                        "no",
                        "yes"
                    ]
                }
            ],
            "types": [
                {
                    "name": "modeltype",
                    "values": [
                        {
                            "name": {
                                "value": "xza plus"
                            }
                        },
                        {
                            "name": {
                                "value": "xz plus"
                            }
                        }
                    ]
                },
                {
                    "name": "varianttype",
                    "values": [
                        {
                            "name": {
                                "value": "diesel"
                            }
                        },
                        {
                            "name": {
                                "value": "petrol"
                            }
                        }
                    ]
                },
                {
                    "name": "yesnomodeslottype",
                    "values": [
                        {
                            "name": {
                                "value": "no, i am not interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am not interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am not"
                            }
                        },
                        {
                            "name": {
                                "value": "no"
                            }
                        },
                        {
                            "name": {
                                "value": "yes, i am interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am"
                            }
                        },
                        {
                            "name": {
                                "value": "yes"
                            }
                        }
                    ]
                },
                {
                    "name": "yesnoinfotainmentslottype",
                    "values": [
                        {
                            "name": {
                                "value": "no, i am not interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am not interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am not"
                            }
                        },
                        {
                            "name": {
                                "value": "no"
                            }
                        },
                        {
                            "name": {
                                "value": "yes, i am interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am interested"
                            }
                        },
                        {
                            "name": {
                                "value": "i am"
                            }
                        },
                        {
                            "name": {
                                "value": "yes"
                            }
                        }
                    ]
                }
            ]
        },
        "dialog": {
            "intents": [
                {
                    "name": "TATANexonmodelvariantfeatureIntent",
                    "confirmationRequired": false,
                    "prompts": {},
                    "slots": [
                        {
                            "name": "modelTATANexon",
                            "type": "modeltype",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Intent-TATANexonmodelvariantfeatureIntent.IntentSlot-modelTATANexon"
                            }
                        },
                        {
                            "name": "variantTATANexon",
                            "type": "varianttype",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Intent-TATANexonmodelvariantfeatureIntent.IntentSlot-variantTATANexon"
                            }
                        }
                    ]
                },
                {
                    "name": "TATANexonmodefeatureIntent",
                    "confirmationRequired": false,
                    "prompts": {},
                    "slots": [
                        {
                            "name": "yesnomodeslot",
                            "type": "yesnomodeslottype",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Intent-TATANexonmodefeatureIntent.IntentSlot-yesnomodeslot"
                            }
                        }
                    ]
                },
                {
                    "name": "TATANexoninfotainmentfeatureIntent",
                    "confirmationRequired": false,
                    "prompts": {},
                    "slots": [
                        {
                            "name": "yesnoinfotainmentslot",
                            "type": "yesnoinfotainmentslottype",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Intent-TATANexoninfotainmentfeatureIntent.IntentSlot-yesnoinfotainmentslot"
                            }
                        }
                    ]
                }
            ]
        },
        "prompts": [
            {
                "id": "Elicit.Intent-TATANexonmodelvariantfeatureIntent.IntentSlot-modelTATANexon",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": " The model that you are currently driving, is it a XZ Plus or a XZA Plus?"
                    }
                ]
            },
            {
                "id": "Elicit.Intent-TATANexonmodelvariantfeatureIntent.IntentSlot-variantTATANexon",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": "which variant do you seek information on, petrol or diesel?"
                    },
                    {
                        "type": "PlainText",
                        "value": "which variant are you interested in, petrol or diesel?"
                    }
                ]
            },
            {
                "id": "Elicit.Intent-TATANexonmodefeatureIntent.IntentSlot-yesnomodeslot",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": "Are you interested in the different modes offered by TATA Nexon?"
                    }
                ]
            },
            {
                "id": "Elicit.Intent-TATANexoninfotainmentfeatureIntent.IntentSlot-yesnoinfotainmentslot",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": "Are you excited to know about TATA Nexon's feature rich infotainment system?"
                    }
                ]
            }
        ]
    }
}

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

// 1. Text strings ================================================================================
//    Modify these strings and messages to change the behavior of your Lambda function

const welcomeOutput = "Hello! Starting a Test Drive? No worries, for I am here to help. Currently you are taking a Test Drive in a TATA Nexon. The Nexon range by TATA Motors is a stylish looking and powerful sub-compact SUV, which is feature loaded, following the IMPACT design philosophy, making ride and handling quite sorted.";
const welcomeReprompt = "Would you be interested to know about TATA Nexon Test Drive?";
const helpOutput = 'You can demonstrate the delegate directive by saying "TATA Nexon Test Drive".';
const helpReprompt = 'Try saying "TATA Nexon Test Drive".';


//CONSTANTS

const slotsToOptions2Map = {
  'yes': 0,
  'i am': 1,
  'i am interested': 2,
  'yes, i am interested': 3,
  'no': 4,
  'i am not': 5,
  'i am not interested': 6,
  'no, i am not interested': 7,
};

const slotsToOptions1Map = {
  'yes': 0,
  'i am': 1,
  'i am interested': 2,
  'yes, i am interested': 3,
  'no': 4,
  'i am not': 5,
  'i am not interested': 6,
  'no, i am not interested': 7,
};

const slotsToOptionsMap = {
  'xz plus-petrol': 0,
  'xz plus-diesel': 1,
  'xza plus-petrol': 2,
  'xza plus-diesel': 3,  
};

const facts2 = [
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' TATA Nexon comes with a host of safety features. Would you be interested in it? '},
  { text: ' TATA Nexon comes with a host of safety features. Would you be interested in it? '},
  { text: ' TATA Nexon comes with a host of safety features. Would you be interested in it? '},
  { text: ' TATA Nexon comes with a host of safety features. Would you be interested in it? '},
];

const facts1 = [
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' TEXT INFO '},
  { text: ' May I interest you in the features of the infotainment system present? '},
  { text: ' May I interest you in the features of the infotainment system present? '},
  { text: ' May I interest you in the features of the infotainment system present? '},
  { text: ' May I interest you in the features of the infotainment system present? '},
];

const facts = [
  { model: 'TEXT INFO', variant: 'TEXT INFO'},
  { model: 'TEXT INFO', variant: 'TEXT INFO'},
  { model: 'TEXT INFO', variant: 'TEXT INFO'},
  { model: 'TEXT INFO', variant: 'TEXT INFO'},
];

// 1. Intent Handlers =============================================

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const responseBuilder = handlerInput.responseBuilder;
    return responseBuilder
      .speak(welcomeOutput)
      .reprompt(welcomeReprompt)
      .withShouldEndSession(false)
      .getResponse();
  },
};

const InProgressTATANexonmodelvariantfeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'TATANexonmodelvariantfeatureIntent' &&
      request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .withShouldEndSession(false)
      .getResponse();
  },
};

const CompletedTATANexonmodelvariantfeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' && request.intent.name === 'TATANexonmodelvariantfeatureIntent';
  },
  handle(handlerInput) {
    console.log('TATANexonmodelvariantfeatureIntent - handle');

    const responseBuilder = handlerInput.responseBuilder;
    const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
    const slotValues = getSlotValues(filledSlots);

    //LOOK UP KEY-MAP RESOLUTION
    const key = `${slotValues.modelTATANexon.resolved}-${slotValues.variantTATANexon.resolved}`;
    const information = facts[slotsToOptionsMap[key]];
    // compose speechOutput that simply reads all the collected slot values

  //let speechOutput = "";
  //NEW RESPONSE
    const speechOutput = ` So you're interested in the ${slotValues.modelTATANexon.synonym} model, ${slotValues.variantTATANexon.synonym} variant \. Good to know \!` + ` ${information.model} ${information.variant} ` + ` Would you like to know about the different modes available \? `;

    /*// activity is optional so we'll add it to the output
    // only when we have a valid activity
    if (slotValues.factMode) {
      speechOutput += slotValues.factMode;
    } else {
      speechOutput += " So you're interested in the";
    }

    // Now let's recap the trip
    speechOutput = `${speechOutput} ${slotValues.variantTATANexon.synonym} ${slotValues.modeTATANexon.synonym} mode and want to know about the ${slotValues.infotainmentTATANexon.synonym} infotainment system \. Good to know \!`;*/

    return responseBuilder
      .speak(speechOutput)
      .withShouldEndSession(false)
      .getResponse();
  },
};

const InProgressTATANexoninfotainmentfeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'TATANexoninfotainmentfeatureIntent' &&
      request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .withShouldEndSession(false)
      .getResponse();
  },
};

const CompletedTATANexoninfotainmentfeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' && request.intent.name === 'TATANexoninfotainmentfeatureIntent';
  },
  handle(handlerInput) {
    console.log('TATANexoninfotainmentfeatureIntent - handle');

    const responseBuilder = handlerInput.responseBuilder;
    const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
    const slotValues = getSlotValues(filledSlots);

    const key2 = `${slotValues.yesnoinfotainmentslot.resolved}`;
      const information2 = facts2[slotsToOptions2Map[key2]];

  //NEW RESPONSE
    const speechOutput = ` ${information2.text} `;


    /*// activity is optional so we'll add it to the output
    // only when we have a valid activity
    if (slotValues.factMode) {
      speechOutput += slotValues.factMode;
    } else {
      speechOutput += " So you're interested in the";
    }

    // Now let's recap the trip
    speechOutput = `${speechOutput} ${slotValues.variantTATANexon.synonym} ${slotValues.modeTATANexon.synonym} mode and want to know about the ${slotValues.infotainmentTATANexon.synonym} infotainment system \. Good to know \!`;*/
      //delete this.event.request.intent.slots.yesnoinfotainmentslot.resolutions;
    return responseBuilder
      .speak(speechOutput)
      .withShouldEndSession(false)
      .getResponse();
  },
};

const InProgressTATANexonmodefeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'TATANexonmodefeatureIntent' &&
      request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .withShouldEndSession(false)
      .getResponse();
  },
};


const CompletedTATANexonmodefeatureHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' && request.intent.name === 'TATANexonmodefeatureIntent';
  },
  handle(handlerInput) {
    console.log('TATANexonmodefeatureIntent - handle');

    const responseBuilder = handlerInput.responseBuilder;
    const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
    const slotValues = getSlotValues(filledSlots);

    const key1 = `${slotValues.yesnomodeslot.resolved}`;
      const information1 = facts1[slotsToOptions1Map[key1]];

  //NEW RESPONSE
    const speechOutput = ` ${information1.text} `;
    //` Would you be interested in the level nex technology infotainment system? `;
    /*// activity is optional so we'll add it to the output
    // only when we have a valid activity
    if (slotValues.factMode) {
      speechOutput += slotValues.factMode;
    } else {
      speechOutput += " So you're interested in the";
    }

    // Now let's recap the trip
    speechOutput = `${speechOutput} ${slotValues.variantTATANexon.synonym} ${slotValues.modeTATANexon.synonym} mode and want to know about the ${slotValues.infotainmentTATANexon.synonym} infotainment system \. Good to know \!`;*/
      //delete this.event.request.intent.slots.yesnomodeslot.resolutions;
    return responseBuilder
      .speak(speechOutput)
      .withShouldEndSession(false)
      .getResponse();
  },
};




const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    const responseBuilder = handlerInput.responseBuilder;
    return responseBuilder
      .speak(helpOutput)
      .reprompt(helpReprompt)
      .getResponse();
  },
};




const CancelStopHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      (request.intent.name === 'AMAZON.CancelIntent' || request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    const responseBuilder = handlerInput.responseBuilder;
    const speechOutput = 'Okay, talk to you later! ';

    return responseBuilder
      .speak(speechOutput)
      .withShouldEndSession(true)
      .getResponse();
  },
};

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

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

    console.log(`Original Request was: ${JSON.stringify(request, null, 2)}`);
    console.log(`Error handled: ${error}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can not understand the command.  Please say again.')
      .reprompt('Sorry, I can not understand the command.  Please say again.')
      .getResponse();
  },
};

// 2. Helper Functions ============================================================================

function getSlotValues(filledSlots) {
  const slotValues = {};

  console.log(`The filled slots: ${JSON.stringify(filledSlots)}`);
  Object.keys(filledSlots).forEach((item) => {
    const name = filledSlots[item].name;

    if (filledSlots[item] &&
      filledSlots[item].resolutions &&
      filledSlots[item].resolutions.resolutionsPerAuthority[0] &&
      filledSlots[item].resolutions.resolutionsPerAuthority[0].status &&
      filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code) {
      switch (filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code) {
        case 'ER_SUCCESS_MATCH':
          slotValues[name] = {
            synonym: filledSlots[item].value,
            resolved: filledSlots[item].resolutions.resolutionsPerAuthority[0].values[0].value.name,
            isValidated: true,
          };
          break;
        case 'ER_SUCCESS_NO_MATCH':
          slotValues[name] = {
            synonym: filledSlots[item].value,
            resolved: filledSlots[item].value,
            isValidated: false,
          };
          break;
        default:
          break;
      }
    } else {
      slotValues[name] = {
        synonym: filledSlots[item].value,
        resolved: filledSlots[item].value,
        isValidated: false,
      };
    }
  }, this);

  return slotValues;
}

/*function getRandomPhrase(array) {
  // the argument is an array [] of words or phrases
  const i = Math.floor(Math.random() * array.length);
  return (array[i]);
}*/

// 4. Exports handler function and setup ===================================================
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    InProgressTATANexonmodelvariantfeatureHandler,
    CompletedTATANexonmodelvariantfeatureHandler,
    InProgressTATANexonmodefeatureHandler,
    CompletedTATANexonmodefeatureHandler,
    InProgressTATANexoninfotainmentfeatureHandler,
    CompletedTATANexoninfotainmentfeatureHandler,
    CancelStopHandler,
    HelpHandler,
    SessionEndedHandler,
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

person monikr_on_east    schedule 16.11.2018    source источник
comment
Поделитесь небольшой дополнительной информацией, на которую стоит обратить внимание, например вашей моделью взаимодействия, фрагментом кода, запросом и ответом в формате JSON.   -  person johndoe    schedule 16.11.2018
comment
@CicilThomas, пожалуйста, найдите запрошенное.   -  person monikr_on_east    schedule 19.11.2018


Ответы (1)


Вам нужно поработать над дизайном вашей модели взаимодействия. Вы не должны использовать пользовательские YesIntent и NoIntent, вместо этого используйте предопределенные AMAZON.YesIntent и AMAZON.NoIntent.

Насколько я понял из вашей модели взаимодействия, вам нужно всего два слота, model и variant. Подумайте об этом так:

[TestDriveIntent]
start a test drive
I want a test drive
start a test drive on {model}
begin test drive on {model} {variant} 

где {model} и {variant} - два слота, необходимые для выполнения вашего намерения. После запуска этого диалога вы можете делегировать эти слоты для заполнения или активировать их. Вы также можете использовать директивы ConfirmSlot и ConfirmIntent, чтобы получить подтверждение от пользователя перед продолжением. Преимущество здесь в том, что вам не нужно обрабатывать эти «да» и «нет», вводимые пользователем для этих подтверждений.

person johndoe    schedule 19.11.2018
comment
Я попытался добавить AMAZON.YesIntent, AMAZON.NoIntent и использовать sessionAttributes, как указано здесь stackoverflow.com/questions/52077201/ amazon-alexa-skill, теперь я не могу получить даже первый ответ - person monikr_on_east; 20.11.2018
comment
Я сделал. Дело в том, что я не могу понять, как использовать атрибуты sessionAttributes в моей лямбда-функции. - person monikr_on_east; 21.11.2018
comment
В ответе, который вы упомянули, используйте ask-sdk-v1. Для v2 используйте var attributes = handlerInput.attributesManager.getSessionAttributes(), чтобы получить атрибуты, и вы можете сделать attributes.yourSessionAttribute = "value" и, наконец, установить его с помощью'handlerInput.attributesManager.setSessionAttributes(attributes) - person johndoe; 21.11.2018
comment
Я смог это сделать. Спасибо большое за вашу помощь! - person monikr_on_east; 23.11.2018