Intent ConfirmationStatus cannot be changed with Dialog.Delegate directive

≯℡__Kan透↙ 提交于 2021-01-28 05:25:53

问题


I have a dialog where I delegate Alexa to collect two slots and ask the confirmation prompt. If the user says "no" to the confirmation prompt, I want to restart the dialog by deleting the slot values and setting the intent confirmationStatus to "NONE".

While Alexa starts to elicit the first slot, the confirmation status remains as "DENIED" which leads to a loop. I used the method described here to reset the status.

This is the updated intent sent back from my skill

{
  "name": "StartSingleGameIntent",
  "confirmationStatus": "NONE",
  "slots": {
    "player_one": {
      "name": "player_one",
      "confirmationStatus": "NONE",
      "source": "USER"
    },
    "player_two": {
      "name": "player_two",
      "confirmationStatus": "NONE",
      "source": "USER"
    }
  }
}

But the next request still has the "DENIED" status:

{
  "name": "StartSingleGameIntent",
  "confirmationStatus": "DENIED",
  "slots": {
    "player_one": {
      "name": "player_one",
      "value": "ben",
      "confirmationStatus": "NONE",
      "source": "USER"
    },
    "player_two": {
      "name": "player_two",
      "confirmationStatus": "NONE"
    }
  }
}

Here are my handlers:

const StartSingleGameStartedIntentHandler = {
  canHandle(handlerInput) {
    return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
      Alexa.getIntentName(handlerInput.requestEnvelope) === 'StartGameIntent' &&
      Alexa.getDialogState(handlerInput.requestEnvelope) === 'STARTED';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
             .addDelegateDirective(handlerInput.requestEnvelope.request.intent).getResponse();
  }
};
const StartSingleGameInProgressIntentHandler = {
  canHandle(handlerInput) {
    return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
      Alexa.getIntentName(handlerInput.requestEnvelope) === 'StartGameIntent' &&
      Alexa.getDialogState(handlerInput.requestEnvelope) === 'IN_PROGRESS';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    console.log("Dialog in progress %s", JSON.stringify(currentIntent));
    if (currentIntent.confirmationStatus === "DENIED") {
      let intent = handlerInput.requestEnvelope.request.intent;
      intent.confirmationStatus = "NONE";
      Object.keys(intent.slots).forEach(slotName => {
        const slot = intent.slots[slotName];
        delete slot.value;
      });
      console.log("New intent %s", JSON.stringify(intent));
      const speechText = "Ok, let's try again";
      return handlerInput.responseBuilder
        .speak(speechText)
        .addDirective({
          type: "Dialog.Delegate",
          updatedIntent: intent
        })
        .getResponse();

    }
    // if Intent is confirmed, delegate to complete dialog
    return handlerInput.responseBuilder.addDelegateDirective(currentIntent).getResponse();
  }
};
const StartSingleGameCompletedIntentHandler = {
  canHandle(handlerInput) {
    return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
      Alexa.getIntentName(handlerInput.requestEnvelope) === 'StartGameIntent' &&
      Alexa.getDialogState(handlerInput.requestEnvelope) === 'COMPLETED';
  },
  handle(handlerInput) {
    console.log("Status COMPLETED");
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    const playerOne = currentIntent.slots.player_one.value;
    const playerTwo = currentIntent.slots.player_two.value;
    const speech = 'Ok, ' + playerOne + ' versus ' + playerTwo + '!';
    return handlerInput.responseBuilder.speak(speech).withShouldEndSession(true).getResponse();
  }
};

And here is the relevant part from the interaction model

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "kicker tracker",
      "intents": [
        {
          "name": "StartSingleGameIntent",
          "slots": [
            {
              "name": "player_one",
              "type": "AMAZON.FirstName",
              "samples": [
                "{player_one}"
              ]
            },
            {
              "name": "player_two",
              "type": "AMAZON.FirstName",
              "samples": [
                "{player_two}"
              ]
            }
          ],
          "samples": [
            "{player_one} versus {player_two}",
            "{player_one} against {player_two}"
          ]
        }
      ],
      "types": []
    },
    "dialog": {
      "intents": [
        {
          "name": "StartGameIntent",
          "delegationStrategy": "SKILL_RESPONSE",
          "confirmationRequired": true,
          "prompts": {
            "confirmation": "Confirm.Intent.331442628749"
          },
          "slots": [
            {
              "name": "player_one",
              "type": "AMAZON.FirstName",
              "confirmationRequired": false,
              "elicitationRequired": true,
              "prompts": {
                "elicitation": "Elicit.Slot.1074854715089.1393950695631"
              }
            },
            {
              "name": "player_two",
              "type": "AMAZON.FirstName",
              "confirmationRequired": false,
              "elicitationRequired": true,
              "prompts": {
                "elicitation": "Elicit.Slot.1074854715089.404108193608"
              }
            }
          ]
        }
      ],
      "delegationStrategy": "ALWAYS"
    },
    "prompts": [
      {
        "id": "Elicit.Slot.1074854715089.1393950695631",
        "variations": [
          {
            "type": "PlainText",
            "value": "Who is the first player?"
          }
        ]
      },
      {
        "id": "Elicit.Slot.1074854715089.404108193608",
        "variations": [
          {
            "type": "PlainText",
            "value": "Who plays against {player_one} ?"
          }
        ]
      },
      {
        "id": "Confirm.Intent.331442628749",
        "variations": [
          {
            "type": "PlainText",
            "value": "{player_one} versus {player_two}, correct?"
          }
        ]
      }
    ]
  }
}

来源:https://stackoverflow.com/questions/59895154/intent-confirmationstatus-cannot-be-changed-with-dialog-delegate-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!