【问题标题】:ASK error, TypeError: Cannot read property 'type' of undefinedASK 错误,TypeError:无法读取未定义的属性“类型”
【发布时间】:2018-09-07 08:13:29
【问题描述】:

我正在创建一项技能,该技能将通过 Alexa 从 DynamoDB 表中回调不同日期和时间的不同事件。

我的 3 列是数据、时间和事件

我已将 Lambda 函数中的分区和排序键定义为

let GetMachineStateIntent = (context, callback) => {    
  var params = {
    TableName: "updatedincident",
    Key: {
        date: "2017-03-21",
        time: "07:38",
        incident: "Blocked Primary",
    }
  };

当我尝试测试我的技能时,我似乎无法正确回忆事件,我在 Cloudwatch 中遇到的错误是:

2018-03-28T14:48:53.397Z 042319cb-4a3e-49ae-8b33-1641367107d4 技能处理程序发生意外错误! TypeError:无法读取未定义的属性“类型” 在exports.handler.e (/var/task/index.js:70:16)

还有:

2018-03-28T14:48:53.417Z 042319cb-4a3e-49ae-8b33-1641367107d4 { "errorMessage": "意外错误" }

这是我的 index.js 代码

var AWSregion = 'us-east-1';  // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
AWS.config.update({
    region: "'us-east-1'"
});

let GetMachineStateIntent = (context, callback) => {    
  var params = {
    TableName: "updatedincident",
    Key: {
      date: "2018-03-28",
      time: "04:23",
    }
  };
  dbClient.get(params, function (err, data) {
    if (err) {
       // failed to read from table for some reason..
       console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
       // let skill tell the user that it couldn't find the data 
       sendResponse(context, callback, {
          output: "the data could not be loaded from your database",
          endSession: false
       });
    } else {
       console.log('loaded data item:\n' + JSON.stringify(data.Item, null, 2));
       // assuming the item has an attribute called "incident"..
       sendResponse(context, callback, {
          output: data.Item.incident,
          endSession: false
       });
    }
  });
};


function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
}

exports.handler = (event, context, callback) => {
  try {
    var request = event.request;
    if (request.type === "LaunchRequest") {
      sendResponse(context, callback, {
        output: "welcome to my skill. what data are you looking for?",
        endSession: false
      });
  }
    else if (request.type === "IntentRequest") {
      let options = {};         
      if (request.intent.name === "GetMachineStateIntent") {
        GetMachineStateIntent(context, callback);
      } else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
        sendResponse(context, callback, {
          output: "ok. good bye!",
          endSession: true
        });
      }
      else if (request.intent.name === "AMAZON.HelpIntent") {
        sendResponse(context, callback, {
          output: "you can ask me about incidents that have happened",
          reprompt: "what can I help you with?",
          endSession: false
        });
      }
      else {
        sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
        });
      }
    }
    else if (request.type === "SessionEndedRequest") {
      sendResponse(context, callback, ""); // no response needed
    }
    else {
      // an unexpected request type received.. just say I don't know..
      sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
      });
    }
  } catch (e) {
    // handle the error by logging it and sending back an failure
    console.log('Unexpected error occurred in the skill handler!', e);
    if(typeof callback === 'undefined') {
       context.fail("Unexpected error");
    } else {
       callback("Unexpected error");
    }
  }
};

这是我的处理程序 GetMachineState.js

function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
}

exports.handler = (event, context, callback) => {
  try {
    var request = event.request;
    if (request.type === "LaunchRequest") {
      sendResponse(context, callback, {
        output: "welcome to my skill. what do you want to find?",
        endSession: false
      });
    }
    else if (request.type === "IntentRequest") {
      let options = {};         
      if (request.intent.name === "GetMachineStateIntent") {
        // this is where we will wire up the dynamo call
        // for now, just send a simple response and end the session
        sendResponse(context, callback, {
          output: "cinema not implemented yet!",
          endSession: true
        });
      } else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
        sendResponse(context, callback, {
          output: "ok. good bye!",
          endSession: true
        });
      }
      else if (request.intent.name === "AMAZON.HelpIntent") {
        sendResponse(context, callback, {
          output: "you can ask me about incidents that have happened",
          reprompt: "what can I help you with?",
          endSession: false
        });
      }
      else {
        sendResponse(context, callback, {
          output: "I don't know that one! Good bye!",
          endSession: true
        });
      }
    }
    else if (request.type === "SessionEndedRequest") {
      sendResponse(context, callback, ""); // no response needed
    }
    else {
      // an unexpected request type received.. just say I don't know..
      sendResponse(context, callback, {
          output: "I don't know that one! Good bye!",
          endSession: true
      });
    }
  } catch (e) {
    // handle the error by logging it and sending back an failure
    console.log('Unexpected error occurred in the skill handler!', e);
    if(typeof callback === 'undefined') {
       context.fail("Unexpected error");
    } else {
       callback("Unexpected error");
    }
  }
};

【问题讨论】:

    标签: aws-lambda amazon-dynamodb alexa alexa-skills-kit


    【解决方案1】:

    无法确定这是否是问题所在,因为您尚未共享 index.js 文件中的代码。您收到的错误消息告诉您问题出现在 index.js 文件的第 70 行,因此您应该查看那里,找出问题所在。

    但是,基于您也在another question 上发表评论这一事实,我敢猜测您遇到的问题是您使用了我提供的代码 sn-p the answer to that question 并且错误来自取消引用 request.type

    您必须确保将请求变量设置为来自事件的实际请求,如下所示:var request = event.request where event is provided from exports.handler = (event, context, callback) =&gt; {

    例如:

    exports.handler = (event, context, callback) => {
      var request = event.request;
      if (request.type === "IntentRequest" 
          // make suret the name of the intent matches the one in your interaction model
       && request.intent.name == "GetMachineStateIntent") {
        var dateSlot = request.intent.slots.Date != null ?
                       request.intent.slots.Date.value : "unknown date";
        var timeSlot = request.intent.slots.Time != null ?
                       request.intent.slots.Time.value : "unknown time";
    
        // respond with speech saying back what the skill thinks the user requested
        sendResponse(context, callback, {
           output: "You wanted the machine state at " 
                  + timeSlot + " on " + dateSlot,
           endSession: true
        });
      } else {
        // TODO:  handle other types of requests..
        sendResponse(context, callback, {
           output: "I don't know how to handle this request yet!"
           endSession: true
        }); 
      } 
    };
    
    function sendResponse(context, callback, responseOptions) {
      if(typeof callback === 'undefined') {
        context.succeed(buildResponse(responseOptions));
      } else {
        callback(null, buildResponse(responseOptions));
      }
    }
    
    function buildResponse(options) {
      var alexaResponse = {
        version: "1.0",
        response: {
          outputSpeech: {
            "type": "SSML",
            "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
          },
          shouldEndSession: options.endSession
        }
      };
      if (options.repromptText) {
        alexaResponse.response.reprompt = {
          outputSpeech: {
            "type": "SSML",
            "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
          }
        };
      }
      return alexaResponse;
    } 
    

    【讨论】:

    • 嗨,迈克,我已经在这个问题中添加了我的 index.js 以及我的处理程序,我真的希望你有最好的复活节!
    • 那么为什么你有两个文件? index.js 一个 GetMachineState.js?第二个是干什么用的?你是如何测试技能的?使用 Alexa 还是其他方式?
    • GetMachineState.js 是我相信的处理程序,我正在使用 alexa 开发人员控制台进行测试,抱歉,回复晚了很多事情发生了
    • 这取决于您希望它如何工作。您可以修改回复以给出机器的状态,而不是重复/确认问题。或者,如果您保留确认,您可以将 AMAZON.YesIntent 添加到您的交互模型中,并在您的技能中处理它以返回答案。对于后者,您还必须打开麦克风来记录用户的响应,这可以通过在您目前的响应中将 shouldEndSession 设置为 false 来完成。为此,您还必须将查询参数存储在技能会话属性中。总之有点复杂。
    • 是的,当然。就像我说的,让查询持久化的最简单方法可能是使用会话属性。看看这篇博文。它讨论了在类似任务中使用会话属性:developer.amazon.com/blogs/alexa/post/…
    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多