Alexa Skill Learning: TypeError: Невозможно прочитать свойство 'value' из undefined - PullRequest
0 голосов
/ 21 ноября 2018

Я получаю сообщение об ошибке, когда пытаюсь проверить свои базовые навыки (я пытаюсь научиться их создавать).Вот ошибка из журнала:

2018-11-21T16: 10: 55.759Z 06a36441-eda8-11e8-a421-f996bf66c592 Неожиданное исключение 'Ошибка типа: не удалось прочитать значение' значения 'из неопределенного значения':

TypeError: Невозможно прочитать свойство 'value' undefined в Object.getSuggestion (/var/task/index.js:31:54) в emitNone (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)

в файле export.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": "Невозможно прочитать свойство 'city' 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

После долгих попыток разных вещей, я приобрел навык бега с помощью Бала Симпсона!

Тем не менее, умение по-прежнему выдает ошибку, когда пользователь произносит название города.В моей модели взаимодействия должна быть ошибка:

   {
        "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": []
            }
        }
    }

Приближение !!

В качестве последней попытки:

Вот мой индекс.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"
                            }
                        }
                    ]
                }
            ]
        }
    }
}

1 Ответ

0 голосов
/ 25 ноября 2018

ки.alexa-sdk устарела ссылка .Чтобы получить новый SDK, сделайте это.

1 - Создать новую функцию в Lambda.

2 - Выберите безсерверный репозиторий приложений AWS.alexa-skills-kit-nodejs-factskill

3 - Выберите alexa-skill-kit-nodejs-factskill.

4 - Нажмите на развертывание.После развертывания нажмите на функции, и вы увидите новую созданную функцию с именем aws-serverless-repository-alexaskillskitnodejsfact-NR8HPILH8WNI.enter image description here

5 - Удалить код и заменить код этим.enter image description here

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 на новую лямбда-ARN.enter image description here

Чтобы добавить тип слота:

enter image description here

Укажите слот в ваших примерах фразы следующим образом:

enter image description here

Измените название вашего слота на city:

enter image description here

Так что вместо musicStations будет город.Убедитесь, что вы ввели три значения в значения слотов, как это:

Добавьте свои собственные значения слотов в CITY_NAMES: Add slot values

Если вы все сделали правильно, ваша модель взаимодействия должна выглядеть примерно так:

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

Тестирование лямбда-кода

В раскрывающемся меню выберите «Настроить тест».События'.enter image description here

Создайте новое тестовое событие с 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.Возможно, имеются дополнительные сведения об ошибке.

enter image description here

...