I've been working on an audio player for the Amazon Echo. Amazon provided a good example to work off of (https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs). I'm coming from Python and node.js is still new to me, so this has been a fun exercise.
I have multiple streams that I'd like to play based on the user's timezone. As the Amazon Echo doesn't have an easy way to do this, I've decided to prompt the user for their zipcode and use that to determine their timezone.
Initial attempt used a JSON file of all relevant zipcode/timezones pairs, but it took too long to load.
Attempts to load them into a database met with mixed results, as I was having trouble configuring the Alexa skill to use multiple DBs. (I'm using one to track user sessions.)
Eventually, I settled on using a third-party API to determine the location (https://www.zipcodeapi.com/API#zipToLoc). Testing in the node shell went swimmingly, so I uploaded it to my lambda to test.
Unfortunately, tests have been giving me "Cannot read property 'body' of undefined".
Offending Code
var constants = require(constants);
var request = require(request);
var zipcode = 85223; // Normally, this is taken from the intent.
var request_string = 'https://www.zipcodeapi.com/rest/' + constants.zipAPIKey + '/info.json/' + zipcode + '/degrees';
var bd = request(request_string, function(error, response, body){
return body;
});
var proc_body = JSON.parse(bd.response.body); // THE PROBLEM LINE
if (proc_body.hasOwnProperty('error_code')){
var message = 'An error occurred. Try again later.';
console.log("ZipCodeAPI Error : %j", proc_body.error_msg);
this.attributes['utc'] = -5; // Default to EST
} else {
this.attributes['utc'] = proc_body.timezone.utc_offset_sec / 3600; // utc_offset_sec is in seconds. Bump it back to hours.
var message = 'Your system has been configured.';
}
Courtesy of the shell: JSON.parse(bd.response.body)
{
zip_code: '85223',
lat: 32.740013,
lng: -111.679788,
city: 'Arizona City',
state: 'AZ',
timezone:
{ timezone_identifier: 'America/Phoenix',
timezone_abbr: 'MST',
utc_offset_sec: -25200,
is_dst: 'F' },
acceptable_city_names: []
}
As I said before, it works fine while in the shell. I'm not sure why it's giving me issues in the lambda. Is the request asynchronous, and the Echo isn't waiting to hear back from the API? Did I not configure something correctly?
I appreciate any help you're able to provide. Thank you for your time.
EDIT: As per the comment below, I reread the documentation. I'm guessing it's because I was reaching beyond the scope?
'GetZip' : function () {
this.attributes['zipcode'] = this.event.request.intent.slots.zipcode.value;
var request_string = 'https://www.zipcodeapi.com/rest/' + constants.zipKey + '/info.json/' + this.attributes['zipcode'] + '/degrees';
request(request_string, function(error, response, body){
var proc_body = JSON.parse(body);
if (proc_body.hasOwnProperty('error_code')){
var message = 'An error occurred. Try again later.';
console.log("ZipCodeAPI Error : %j", proc_body.error_msg);
this.attributes['utc'] = -5;
} else {
this.attributes['utc'] = proc_body.timezone.utc_offset_sec / 3600;
var message = 'Your system has been configured.';
}
this.handler.state = constants.states.START_MODE;
this.response.speak(message);
controller.play.call(this);
});
I think there's still a scope issue, since this
can't be accessed.