在测试环境中,Alexa决策树技能未得到答案。填充所有必需的意图槽后,尽管dialogState达到COMPLETED

时间:2019-06-18 20:29:52

标签: javascript amazon-web-services aws-lambda alexa-skill

我正在根据亚马逊开发人员的决策树技能来开发一项技能。它的大部分应该只是更改slotToOptions映射和选项数组,口头输出,以及更改Alexa对话框模型以跟上,但是在填充我的最后一个所需的意图槽之后,未达到最终状态。我的输入将按预期映射到意图插槽,并且dialogState达到完成状态。

我尝试更改所需的意图槽的数量,以查看对话框是否以一个槽结束,但是得到的是“对不起,我不明白”这一行。

输入JSON:

{

    },
    "request": {
        "type": "IntentRequest",
        "requestId": "amzn1.echo-api.request.dee28b7f-fa01-4603-924e-0a718e92a1a7",
        "timestamp": "2019-06-18T19:51:56Z",
        "locale": "en-US",
        "intent": {
            "name": "RecommendationIntent",
            "confirmationStatus": "NONE",
            "slots": {
                "Design": {
                    "name": "Design",
                    "value": "led",
                    "resolutions": {
                        "resolutionsPerAuthority": [
                            {
                                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.04a2dc83-565b-418a-bca8-50366ef9b69c.designType",
                                "status": {
                                    "code": "ER_SUCCESS_MATCH"
                                },
                                "values": [
                                    {
                                        "value": {
                                            "name": "LED",
                                            "id": "53e0dbc06e48e3d381ac224fa8bae3df"
                                        }
                                    }
                                ]
                            }
                        ]
                    },
                    "confirmationStatus": "NONE",
                    "source": "USER"
                },

                "ContributingFactor": {
                    "name": "ContributingFactor",
                    "value": "cost",
                    "resolutions": {
                        "resolutionsPerAuthority": [
                            {
                                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.04a2dc83-565b-418a-bca8-50366ef9b69c.ContributingFactorType",
                                "status": {
                                    "code": "ER_SUCCESS_MATCH"
                                },
                                "values": [
                                    {
                                        "value": {
                                            "name": "Cost",
                                            "id": "20b4f77bd00b4f63a49ec8e08f3bf6a6"
                                        }
                                    }
                                ]
                            }
                        ]
                    },
                    "confirmationStatus": "NONE",
                    "source": "USER"
            }
        },
        "dialogState": "COMPLETED"
    }
}

Lambda中的index.js片段(地图和RecommendationIntent处理程序)

const InProgressRecommendationIntent = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;

    return request.type === 'IntentRequest'
      && request.intent.name === 'RecommendationIntent'
      && request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    let prompt = '';

    for (const slotName of Object.keys(handlerInput.requestEnvelope.request.intent.slots)) {
      const currentSlot = currentIntent.slots[slotName];
      if (currentSlot.confirmationStatus !== 'CONFIRMED'
                && currentSlot.resolutions
                && currentSlot.resolutions.resolutionsPerAuthority[0]) {
        if (currentSlot.resolutions.resolutionsPerAuthority[0].status.code === 'ER_SUCCESS_MATCH') {
          if (currentSlot.resolutions.resolutionsPerAuthority[0].values.length > 1) {
            prompt = 'Which would you like';
            const size = currentSlot.resolutions.resolutionsPerAuthority[0].values.length;

            currentSlot.resolutions.resolutionsPerAuthority[0].values
              .forEach((element, index) => {
                prompt += ` ${(index === size - 1) ? ' or' : ' '} ${element.value.name}`;
              });

            prompt += '?';

            return handlerInput.responseBuilder
              .speak(prompt)
              .reprompt(prompt)
              .addElicitSlotDirective(currentSlot.name)
              .getResponse();
          }
        } else if (currentSlot.resolutions.resolutionsPerAuthority[0].status.code === 'ER_SUCCESS_NO_MATCH') {
          if (requiredSlots.indexOf(currentSlot.name) > -1) {
            prompt = `What ${currentSlot.name} are you looking for`;

            return handlerInput.responseBuilder
              .speak(prompt)
              .reprompt(prompt)
              .addElicitSlotDirective(currentSlot.name)
              .getResponse();
          }
        }
      }
    }

    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .getResponse();
  },
};

const CompletedRecommendationIntent = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;

    return request.type === 'IntentRequest'
      && request.intent.name === 'RecommendationIntent'
      && request.dialogState === 'COMPLETED';
  },
  handle(handlerInput) {
    const filledSlots = handlerInput.requestEnvelope.request.intent.slots;

    const slotValues = getSlotValues(filledSlots);

    const key = `${slotValues.Design.resolved}-${slotValues.contributingFactor.resolved}`;
    const material = options[slotsToOptionsMap[key]]; 
  const speechOutput = 
  `You want a/an ${slotValues.Design.resolved} circuit and your contributing factor is ${slotValues.contributingFactor.resolved}. You should consider using ${material.name} as your material`;
    return handlerInput.responseBuilder
      .speak(speechOutput)
      .getResponse();
  },
};

const slotsToOptionsMap = {
  'RF-Performance': 0,
  'LED-Performance': 1,
  'Digital-Performance': 2,
  'Hybrid-Performance': 3,
  'RF-Cost': 4,
  'LED-Cost': 5,
  'Digital-Cost': 6,
  'Hybrid-Cost': 7
};

const options = [
  { name: 'rp', description: ''},
  { name: 'lp', description: ''},
  { name: 'dp', description: ''},
  { name: 'hp', description: ''},
  { name: 'rc', description: ''},
  { name: 'lc', description: ''},
  { name: 'dc', description: ''},
  { name: 'hc', description: ''}

];

当我在错误处理程序中运行console.log(error.trace)时,我在日志中得到了这一行:

2019-06-18T19:51:56.339Z    5b28750f-6084-4fb7-ac04-9b6a892e5ab6    Error handled: Cannot read property 'resolved' of undefined

我希望结果是Alexa从映射中输出材料。没有映射任何实际的材料,但是应该说“鉴于您想要[类型]电路并且[性能或成本]是您的贡献因素,因此您应该使用[材料]。”如果我将RF和成本说成是我的类型和贡献因素,那么我应该使用“ rc”作为我的资料。相反,填满最后一个插槽后的唯一消息是“对不起,我不理解该命令。”我是否必须添加代码来管理shouldEndSession值或其他内容?原始代码满足了所有适当的要求。在达到“对不起,我不明白”的输出JSON中,按您期望的那样,shouldEndSession为false。

0 个答案:

没有答案