【问题标题】:Alexa Skill Learning: TypeError: Cannot read property 'value' of undefinedAlexa 技能学习:TypeError:无法读取未定义的属性“值”
【发布时间】:2019-04-24 09:17:22
【问题描述】:

当我尝试测试我的基本技能(我正在尝试学习如何创建它们)时,我不断收到错误消息。 这是日志中的错误:

2018-11-21T16:10:55.759Z 06a36441-eda8-11e8-a421-f996bf66c592 意外异常'TypeError:无法读取属性'值' 未定义':

TypeError:无法读取未定义的属性“值” 在 emitNone 上的 Object.getSuggestion (/var/task/index.js:31:54) (events.js:86:13) 在 AlexaRequestEmitter.emit (events.js:185:7) 在 AlexaRequestEmitter.EmitEvent (/var/task/node_modules/alexa-sdk/lib/alexa.js:216:10)在 AlexaRequestEmitter.ValidateRequest (/var/task/node_modules/alexa-sdk/lib/alexa.js:181:23) 在 AlexaRequestEmitter.HandleLambdaEvent (/var/task/node_modules/alexa-sdk/lib/alexa.js:126:25)在 AlexaRequestEmitter.value (/var/task/node_modules/alexa-sdk/lib/alexa.js:100:31)

在exports.handler (/var/task/index.js:52:9)

我该如何解决这个问题?

这是我的代码:

var Alexa = require('alexa-sdk');


const APP_ID = 'amzn1.ask.skill.ab07421a-0a92-4c2b-b3bd-998e14286xxx';


const skillData = [
    {
        city: "Austin",
        suggestion: "Austin has some of the most outstanding people."
    },
    {
        city: "San Antonio",
        suggestion: "San Antonio has some of the most outstanding people."    
    },
    {
        city: "Dallas",
        suggestion: "The Dallas metroplex is one of the hottest places."
    }
];


var number = 0;
while(number<3){
var handlers = {
  'LaunchRequest': function () {


      this.emit(':ask', 'Tell me the name of the major city you are closest to'
   },
  'Unhandled': function () {
      this.emit(':ask', 'Try saying a city name like Austin, San Antonio, or Dallas'); 
  },
  'getSuggestion': function() {
      var city = this.event.request.intent.slots.City.value;


      this.emit(':ask', getSuggestion(skillData,'city', city.toUpperCase()).suggestion + '. Give me another city and I\'ll hook you up with the best peeps.');
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', "What can I help you with?", "How can I help?");
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', "Okay!");
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', "Goodbye!");
  },
};
number = number+1;
}


exports.handler = function(event, context, callback){
  var alexa = Alexa.handler(event, context);
  alexa.appId = APP_ID;
  alexa.registerHandlers(handlers);
  alexa.execute();
};


function getSuggestion(arr, propName, cityName) {
  for (var i=0; i < arr.length; i++) {
    if (arr[i][propName] == cityName) {
      return arr[i];
    }
  }
}

更新

我已按照下面的建议进行了一些更改,但是,在初始响应后我仍然收到错误消息。

"errorMessage": "Cannot read property 'city' of undefined"

请查看我的新代码并帮助我解决这个问题:

var Alexa = require('alexa-sdk');

const APP_ID = 'amzn1.ask.skill.ab07421a-0a92-4c2b-b3bd-998e14286xxx';

const skillData = [
    {
        city: 'Austin',
        suggestion: "Austin is blahblahblahblahlshflashdfasldfha blah."
    },
    {
        city: 'San Antonio',
        suggestion: "San Antonio has blahblahblahblahlshflashdfasldfha blah."    
    },
    {
        city: 'Dallas',
        suggestion: "The Dallas metroplex is one of the hottest blahblahblahbla blahblahblahblahblahblah."
    }
];

var number = 0;
while(number<3){
var handlers = {
  'LaunchRequest': function () {
      this.emit(':ask', 'Tell me the name of the major city you are closest to!', 'Which major city are you closest to?');
   },
  'Unhandled': function () {
      this.emit(':ask', "Try saying a city name like Austin, San Antonio, or Dallas"); 
  },
  'getSuggestion': function() {
      var city = this.event.request.intent.slots.city.value;

      this.emit(':ask', getSuggestion(skillData,'city', city.toUpperCase()).suggestion + '. Give me another city and I\'ll hook you up with the best peeps.');
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', "What can I help you with?", "How can I help?");
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', "Okay!");
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', "Goodbye!");
  },
};

number = number+1;
}
exports.handler = function(event, context, callback){
  var alexa = Alexa.handler(event, context);
  alexa.appId = APP_ID;
  alexa.registerHandlers(handlers);
  alexa.execute();
};

function getSuggestion(arr, propName, cityName) {
  for (var i=0; i < arr.length; i++) {

    var prop = arr[i][propName];
    prop = prop.toUpperCase();

    if (prop == cityName) {
      return arr[i];
    }
  }
}

更新 #2

在尝试了很多不同的事情之后,我在 bal Simpson 的帮助下获得了跑步的技能!

但是,当用户说出城市名称时,该技能仍然会出错。我的交互模型一定有错误,如下:

   {
        "interactionModel": {
            "languageModel": {
                "invocationName": "city picker",
                "intents": [
                    {
                        "name": "AMAZON.FallbackIntent",
                        "samples": []
                    },
                    {
                        "name": "AMAZON.CancelIntent",
                        "samples": []
                    },
                    {
                        "name": "AMAZON.HelpIntent",
                        "samples": []
                    },
                    {
                        "name": "AMAZON.StopIntent",
                        "samples": [
                            "stop"
                        ]
                    },
                    {
                        "name": "AMAZON.NavigateHomeIntent",
                        "samples": []
                    },
                    {
                        "name": "getSuggestion",
                        "slots": [],
                        "samples": [
                            "san antonio",
                            "dallas",
                            "austin"
                        ]
                    }
                ],
                "types": []
            }
        }
    }

靠近!!

作为最后的努力:

这是我在 Lambda 中的 index.js。有人介意看这个吗?

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === "LaunchRequest";
  },
  handle(handlerInput) {

    console.log("LaunchRequestHandler");
    let speechText = 'Lets get you into your new home. Tell me the name of the major city you are closest to!';
    let prompt = 'Which major city are you closest to?';

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

const GetSuggestionIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      handlerInput.requestEnvelope.request.intent.name === "getSuggestion"
    );
  },
  handle(handlerInput) {
    let intent = handlerInput.requestEnvelope.request.intent;
    let city = intent.slot.city.value;

    let suggestion = getSuggestion(skillData,'city', city.toUpperCase()).suggestion;

    return handlerInput.responseBuilder
      .speak(suggestion)
      .reprompt('prompt')
      .getResponse();
  }
};

const HelpIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
    );
  },
  handle(handlerInput) {
    const speechText = "Try saying a city name like Austin, San Antonio, or Dallas";
    const promptText = "How can I help?";

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(promptText)
      // .withSimpleCard("City Details", speechText)
      .getResponse();
  }
};

const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      (handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.CancelIntent" ||
        handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.StopIntent" ||
        handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.PauseIntent")
    );
  },
  handle(handlerInput) {

    const speechText = `Seeya later!`;

    return (
      handlerInput.responseBuilder
        .speak(speechText)
        .withShouldEndSession(true)
        .getResponse()
    );
  }
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.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) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Try saying a city name like Austin, San Antonio, or Dallas')
      .reprompt('Try saying a city name like Austin, San Antonio, or Dallas')
      .getResponse();
  },
};

const SystemExceptionHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type ===
      "System.ExceptionEncountered"
    );
  },
  handle(handlerInput) {
    console.log(
      `System exception encountered: ${
      handlerInput.requestEnvelope.request.reason
      }`
    );
  }
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    GetSuggestionIntentHandler,
    CancelAndStopIntentHandler,
    HelpIntentHandler,
    SystemExceptionHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();
  
function getSuggestion(arr, propName, cityName) {
  for (var i=0; i < arr.length; i++) {

    var prop = arr[i][propName];
    prop = prop.toUpperCase();

    if (prop == cityName) {
      return arr[i];
    }
  }
}

这是我在开发者门户中的交互模型:

{
    "interactionModel": {
        "languageModel": {
            "invocationName": "city picker",
            "intents": [
                {
                    "name": "AMAZON.FallbackIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": [
                        "stop"
                    ]
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "getSuggestion",
                    "slots": [
                        {
                            "name": "city",
                            "type": "CITY_NAMES"
                        }
                    ],
                    "samples": [
                        "{city}"
                    ]
                }
            ],
            "types": [
                {
                    "name": "CITY_NAMES",
                    "values": [
                        {
                            "name": {
                                "value": "dallas"
                            }
                        },
                        {
                            "name": {
                                "value": "san antonio"
                            }
                        },
                        {
                            "name": {
                                "value": "austin"
                            }
                        }
                    ]
                }
            ]
        }
    }
}

【问题讨论】:

  • 发布您对 getSuggestion Intent 的回复
  • 请向您的 getSuggestion Intent 发送请求或回复。
  • 当对已经有答案的问题进行更改时,值得养成问自己更改是否会使这些答案无效的习惯。在这种情况下,更改是实质性的,因此最好添加更新,这样问题的新读者就不会从一开始就阅读“更新”。 (出于相同的原因,一些变化是如此剧烈,以至于它们作为一个新问题更好)。黄金法则是确保答案仍然与上面的问题相关。
  • 你是对的!这完全是我的错。感谢您清理它!

标签: node.js aws-lambda alexa alexa-skills-kit


【解决方案1】:

好的。 alexa-sdk 已被弃用 link。要获取新的 SDK,请执行此操作。

1 - 在 Lambda 中创建一个新函数。

2 - 选择 AWS 无服务器应用程序存储库。

3 - 选择 alexa-skills-kit-nodejs-factskill。

4 - 单击部署。部署后,单击函数,您应该会看到刚刚创建的新函数,其名称类似于 aws-serverless-repository-alexaskillskitnodejsfact-NR8HPILH8WNI。

5 - 删除代码并用此代码替换代码。

const Alexa = require('ask-sdk');    
const skillData = [
            {
                city: 'Austin',
                suggestion: "Austin is blahblahblahblahlshflashdfasldfha blah."
            },
            {
                city: 'San Antonio',
                suggestion: "San Antonio has blahblahblahblahlshflashdfasldfha blah."    
            },
            {
                city: 'Dallas',
                suggestion: "The Dallas metroplex is one of the hottest blahblahblahbla blahblahblahblahblahblah."
            }
        ];

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === "LaunchRequest";
  },
  handle(handlerInput) {

    console.log("LaunchRequestHandler");
    let speechText = 'Tell me the name of the major city you are closest to!';
    let prompt = 'Which major city are you closest to?';

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

const GetSuggestionIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      handlerInput.requestEnvelope.request.intent.name === "getSuggestion"
    );
  },
  handle(handlerInput) {
    let intent = handlerInput.requestEnvelope.request.intent;
    let city = intent.slots.city.value;

    let suggestion = getSuggestion(skillData,'city', city.toUpperCase()).suggestion;

    return handlerInput.responseBuilder
      .speak(suggestion)
      .reprompt('prompt')
      .getResponse();
  }
};

const HelpIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
    );
  },
  handle(handlerInput) {
    const speechText = "Try saying a city name like Austin, San Antonio, or Dallas";
    const promptText = "How can I help?";

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(promptText)
      // .withSimpleCard("City Details", speechText)
      .getResponse();
  }
};

const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === "IntentRequest" &&
      (handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.CancelIntent" ||
        handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.StopIntent" ||
        handlerInput.requestEnvelope.request.intent.name ===
        "AMAZON.PauseIntent")
    );
  },
  handle(handlerInput) {

    const speechText = `Goodbye`;

    return (
      handlerInput.responseBuilder
        .speak(speechText)
        .withShouldEndSession(true)
        .getResponse()
    );
  }
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.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) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Try saying a city name like Austin, San Antonio, or Dallas')
      .reprompt('Try saying a city name like Austin, San Antonio, or Dallas')
      .getResponse();
  },
};

const SystemExceptionHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type ===
      "System.ExceptionEncountered"
    );
  },
  handle(handlerInput) {
    console.log(
      `System exception encountered: ${
      handlerInput.requestEnvelope.request.reason
      }`
    );
  }
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    GetSuggestionIntentHandler,
    CancelAndStopIntentHandler,
    HelpIntentHandler,
    SystemExceptionHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

function getSuggestion(arr, propName, cityName) {
  for (var i=0; i < arr.length; i++) {

    var prop = arr[i][propName];
    prop = prop.toUpperCase();

    if (prop == cityName) {
      return arr[i];
    }
  }
}

6 - 访问 developer.amazon.com 并将您的 Alexa Skill 端点更改为新的 lambda ARN。

添加槽类型:

在您的示例短语中指定位置,如下所示:

将您的广告位名称更改为城市:

所以不是musicStations,而是城市。确保您在槽值中输入了三个值,如下所示:

将您的自定义槽值添加到 CITY_NAMES:

如果你做得对,你的交互模型应该是这样的:

                "name": "getSuggestion",
                "slots": [
                    {
                        "name": "city",
                        "type": "CITY_NAMES"
                    }
                ],
                "samples": [
                    "city name is {city}",
                    "{city}"
                ]

测试 Lambda 代码

在下拉菜单中,选择“配置测试事件”。

从您的开发人员测试门户中使用 JSON 创建新的测试事件,应该如下所示。

{
"version": "1.0",
"session": {
    "new": true,
    "sessionId": "amzn1.echo-api.session.XXXXXX",
    "application": {
        "applicationId": "amzn1.ask.skill.XXXXXX"
    },
    "user": {
        "userId": "amzn1.ask.account.XXXXXX"
    }
},
"context": {
    "AudioPlayer": {
        "playerActivity": "IDLE"
    },
    "System": {
        "application": {
            "applicationId": "amzn1.ask.skill.XXXXXX"
        },
        "user": {
            "userId": "amzn1.ask.account.XXXXXX"
        },
        "device": {
            "deviceId": "amzn1.ask.device.XXXXXX",
            "supportedInterfaces": {
                "AudioPlayer": {}
            }
        },
        "apiEndpoint": "https://api.eu.amazonalexa.com",
        "apiAccessToken": "ACCESS_TOKEN"
    },
},
"request": {
    "type": "IntentRequest",
    "requestId": "amzn1.echo-api.request.XXXX",
    "timestamp": "2018-12-03T20:28:29Z",
    "locale": "en-IN",
    "intent": {
        "name": "PlayRadioIntent",
        "confirmationStatus": "NONE",
        "slots": {
            "musicStation": {
                "name": "musicStation",
                "value": "classic rock",
                "resolutions": {
                    "resolutionsPerAuthority": [
                        {
                            "authority": "amzn1.er-authority.XXXX.RadioStations",
                            "status": {
                                "code": "ER_SUCCESS_MATCH"
                            },
                            "values": [
                                {
                                    "value": {
                                        "name": "Classic Rock",
                                        "id": "b8a5bd97a8a02691f9f81dcfb12184dd"
                                    }
                                }
                            ]
                        }
                    ]
                },
                "confirmationStatus": "NONE",
                "source": "USER"
            }
        }
    }
}

点击测试按钮

查看日志

测试结果是这样的吗?要查看日志,请单击logs。它可能包含其他错误详细信息。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多