【问题标题】:Alexa Recursive Intent Delegation when using Confirmations使用确认时的 Alexa 递归意图委托
【发布时间】:2020-07-11 22:26:33
【问题描述】:

我正在编写一个带有意图确认的 Alexa 对话。当确认被拒绝时,我想通过委派这个对话框再次重新启动同一个对话框。我正在按照this 堆栈溢出问题中的描述进行操作。如该问题的解决方案中所述,当dialogState 仍为IN_PROGRESS 时,我进行委托。在我的情况下,Alexa 总是以不太有意义的消息进行响应请求的技能响应存在问题。应用程序日志中没有错误消息。

我的技能模型和lambda代码如下:

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "hello",
      "intents": [
        {
          "name": "UserIntent",
          "slots": [
            {
              "name": "UserName",
              "type": "AMAZON.FirstName",
              "samples": [
                "My name is {UserName}",
                "I am {UserName}",
                "{UserName}"
              ]
            }
          ],
          "samples": [
            "My name is {UserName}",
            "I am {UserName}"
          ]
        }
      ],
      "types": []
    },
    "dialog": {
      "delegationStrategy": "SKILL_RESPONSE",      
      "intents": [
        {
          "name": "UserIntent",
          "confirmationRequired": true,
          "prompts": {
            "confirmation": "Confirm.Intent.UserName"
          },
          "slots": [
            {
              "name": "UserName",
              "type": "AMAZON.FirstName",
              "confirmationRequired": false,
              "elicitationRequired": true,
              "prompts": {
                "elicitation": "Elicit.Slot.UserName"
              }
            }
          ]
        }
      ]
    },
    "prompts": [
      {
        "id": "Elicit.Slot.UserName",
        "variations": [
          {
            "type": "PlainText",
            "value": "What is your name?"
          }
        ]
      },
      {
        "id": "Confirm.Intent.UserName",
        "variations": [
          {
            "type": "PlainText",
            "value": "You are {UserName}. Is this right?"
          }
        ]
      }
    ]
  }
}
const DeniedUserIntentHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'UserIntent' &&
      request.dialogState === 'IN_PROGRESS' &&
      request.intent.confirmationStatus === 'DENIED';
  },

  async handle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    const currentIntent = request.intent;
    const userName = Alexa.getSlotValue(handlerInput.requestEnvelope, 'UserName');

    console.log(`DeniedUserIntentHandler: 
    request.dialogState=${request.dialogState}, request.intent.confirmationStatus=${request.intent.confirmationStatus}, userName=${userName}`);

    return handlerInput.responseBuilder
      .speak('Username was not confirmed. Please try again.')
      .addDelegateDirective({
        name: 'UserIntent',
        confirmationStatus: 'NONE',
        slots: {}
      })
      .getResponse();
  }
};

我错过了什么?

【问题讨论】:

    标签: node.js alexa alexa-skills-kit alexa-skill


    【解决方案1】:

    您没有指定DeniedUserIntentHandler 是否被触发。如果错误是在DeniedUserIntentHandler 内部产生的,那么这是由于Delegate Directive 的格式错误。

    你的回复应该是这样的:

    return handlerInput.responseBuilder
      .speak('Username was not confirmed. Please try again.')
      .addDelegateDirective({
                             "type": "Dialog.Delegate",
                             "updatedIntent": {
                                   name:"UserIntent",
                                   confirmationStatus:"NONE",
                                   slots: {
                                     UserName: {
                                     name:"UserName",
                                     confirmationStatus:"NONE",
                                     source:"USER"
                                     }
                                   }
                                }
                             })
                             .getResponse();
    

    您删除意图的先前状态的原因是您希望意图操作从头开始。

    你也可以像这样使用你的代码:参考https://forums.developer.amazon.com/questions/92334/answering-no-to-intent-confirmation.html?childToView=206243#comment-206243

    currentIntent.confirmationStatus = "NONE";
    Object.keys(currentIntent.slots).forEach(
        (slotName) => {
          var slot = intent.slots[slotName];
          delete slot.value;
          slot.confirmationStatus = "NONE";
        }
    );
    
    var delegatedirective = {"type": "Dialog.Delegate",
                             "updatedIntent": currentIntent};
    

    【讨论】:

      【解决方案2】:

      您现在面临的问题是真正的问题。亚马逊forum 也提到了这个问题。 但是,您可以通过稍作修改来实现类似的行为。 激活槽值确认 UserName删除确认 UserIntent。 您的交互模型如下所示:

      {
      "interactionModel": {
          "languageModel": {
              "invocationName": "demo app",
              "intents": [
                  {
                      "name": "UserIntent",
                      "slots": [
                          {
                              "name": "UserName",
                              "type": "AMAZON.FirstName",
                              "samples": [
                                  "My name is {UserName}",
                                  "I am {UserName}",
                                  "{UserName}"
                              ]
                          }
                      ],
                      "samples": [
                          "My name is {UserName}",
                          "I am {UserName}"
                      ]
                  },
                  {
                      "name": "AMAZON.NavigateHomeIntent",
                      "samples": []
                  }
              ],
              "types": []
          },
          "dialog": {
              "intents": [
                  {
                      "name": "UserIntent",
                      "delegationStrategy": "SKILL_RESPONSE",
                      "confirmationRequired": false,
                      "prompts": {},
                      "slots": [
                          {
                              "name": "UserName",
                              "type": "AMAZON.FirstName",
                              "confirmationRequired": true,
                              "elicitationRequired": true,
                              "prompts": {
                                  "confirmation": "Confirm.Slot.247378890994.1277345498514",
                                  "elicitation": "Elicit.Slot.UserName"
                              }
                          }
                      ]
                  }
              ],
              "delegationStrategy": "ALWAYS"
          },
          "prompts": [
              {
                  "id": "Elicit.Slot.UserName",
                  "variations": [
                      {
                          "type": "PlainText",
                          "value": "What is your name?"
                      }
                  ]
              },
              {
                  "id": "Confirm.Slot.247378890994.1277345498514",
                  "variations": [
                      {
                          "type": "PlainText",
                          "value": "your name is {UserName} , right ?"
                      }
                  ]
              }
          ]
        }
      }
      

      您可以添加这个单一的代码处理程序:

      const UserIntenStartedHandler = {
        canHandle(handlerInput) {
          const request = handlerInput.requestEnvelope.request;
          return request.type === 'IntentRequest' &&
          request.intent.name === 'UserIntent';
        },
        async handle(handlerInput) {
          const request = handlerInput.requestEnvelope.request;
          const currentIntent = Alexa.getIntentName(handlerInput.requestEnvelope);
          const slot = Alexa.getSlot(handlerInput.requestEnvelope, 'UserName');
      
          if (slot.confirmationStatus !== 'CONFIRMED') {
            return handlerInput.responseBuilder
           .addDelegateDirective(request.intent) 
           .getResponse();
          } else {
            return handlerInput.responseBuilder
           .speak('your Final name is ' + slot.value + '. cheers')
           .withShouldEndSession(true)
           .getResponse();
          }
        }  
      };
      

      【讨论】:

        【解决方案3】:

        感谢@tahiat 的回复,我能够找出我原来的问题。在更新的意图中,槽对象必须包含意图的槽(没有值)。但是他的第一个代码 sn-p 包含一个错误。以太币使用

        .addDirective({
          "type": "Dialog.Delegate", 
          "updatedIntent": { 
             name:"UserIntent", 
             ...
          }
        })
        

        或使用

        .addDelegateDirective({
          name:"UserIntent", 
          ...
        })
        

        因为addDelegateDirective 需要一个意图作为参数。

        但现在我面临另一个问题。我在对话框中使用确认。当我在确认被拒绝后回到UserIntent 的初始状态时,我从来没有收到确认消息的提示。这是因为request.intent.confirmationStatus 保留了它的值,即'DENIED',尽管我已将updateIntent 中的它重置为'NONE'

        【讨论】:

        • 好像是here描述的问题。
        猜你喜欢
        • 2020-06-26
        • 1970-01-01
        • 1970-01-01
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多