I'm developing a custom skill and having some trouble with just this intent, that is to say at the very last stage when all conditions are met in the if/else control flow, I mean when it gets to the last else statement, only this one fails to return the expected response, but all returned responses are working just fine, what could I possibly be missing here: Please pay close attention to the last part where resolve(handlerInput.responseBuilder.speak....etc). I'm not sure what I am doing right here, I'd appreciate
const SetDefaultLocationIntentInProgress = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'SetDefaultLocationIntent';
},
handle(handlerInput) {
console.log(`In SetDefaultLocationIntentInProgress`);
let cardTitle = speech.getCardTitle('setdefaultloc1');
let city = '';
let state = '';
let zipcode = '';
const { attributesManager, responseBuilder } = handlerInput;
const sessionAttributes = attributesManager.getSessionAttributes();
const currentIntent = handlerInput.requestEnvelope.request.intent;
if (sessionAttributes[currentIntent.name]) {
const tempSlots = sessionAttributes[currentIntent.name].slots;
for (const key in tempSlots) {
if (tempSlots[key].value && !currentIntent.slots[key].value) {
currentIntent.slots[key] = tempSlots[key];
}
}
}
sessionAttributes[currentIntent.name] = currentIntent;
attributesManager.setSessionAttributes(sessionAttributes);
if (currentIntent.slots.City && currentIntent.slots.City.value) {
// User provided value for City slot
city = currentIntent.slots.City.value;
}
if (currentIntent.slots.State && currentIntent.slots.State.value) {
// User provided value for State slot
state = currentIntent.slots.State.value;
}
if (currentIntent.slots.Zipcode && currentIntent.slots.Zipcode.value) {
// User provided value for Zipcode slot
zipcode = currentIntent.slots.Zipcode.value;
}
debugLog(`City: ${city}, State: ${state}, Zipcode: ${zipcode}`);
let speechOutput = '';
let repromtText = '';
if (city.length === 0 && state.length === 0 && zipcode.length === 0) {
// No values provided by user for city, state or zipcode
speechOutput = speech.getSpeechText('setdefaultloc5');
repromtText = speech.getSpeechText('reprompt2');
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse();
}else if(zipcode.length > 0 && !zipCodeValidator(zipcode) ) {
// user provided a zipcode but it is not a valid US zipcode
let speechObject = speech.getSpeechObject('setdefaultloc7');
speechOutput = util.format(speechObject.text, zipcode);
repromtText = speech.getSpeechText('reprompt3');
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse();
}else {
let params = '';
let lookupFunc = '';
let placeNameLookup = '';
if (zipcode.length > 0 && zipCodeValidator(zipcode)) {
params = zipcode;
lookupFunc = apiCalls.zipcodeLookup;
}else {
if (state.length === 0) {
params = city;
placeNameLookup = city;
}else{
params = `${city}+${state}`;
placeNameLookup = `${city} ${state}`;
}
lookupFunc = apiCalls.placeNameLookup;
}
lookupFunc (params, (error, result, duration) => {
if(error || result === null) {
// API Call failed or result is null
speechOutput = speech.getSpeechText('error2', false);
repromtText = speech.getSpeechText('reprompt3', false);
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse();
}else if (Object.keys(result).length === 0) {
// Returned an empty result
if (zipcode.length > 0) {
// was zipcode
let speechObject = speech.getSpeechObject('setdefaultloc4');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
}else{
// wasn't zipcode
let speechObject = speech.getSpeechObject('setdefaultloc3');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
}
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse();
}else {
// Api Call successfull with result objects length > 0
return new Promise( (resolve, reject) => {
handlerInput.attributesManager.getPersistentAttributes()
.then((attributes) => {
const defaultLoc = {
name: result.name,
lat: result.lat,
lon: result.lon
};
const userId = handlerInput.requestEnvelope.context.System.user.userId;
attributes['defaultLoc'] = defaultLoc;
debugLog("Writing attributes to DynamoDB: " + userId + ", " + "defaultlocation: " + JSON.stringify(defaultLoc));
handlerInput.attributesManager.setSessionAttributes(attributes);
handlerInput.attributesManager.setPersistentAttributes(attributes);
handlerInput.attributesManager.savePersistentAttributes();
let speechObject = speech.getSpeechObject('setdefaultloc22');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
debugLog(`SpeechOutput After saving user location: ${speechOutput}`);
debugLog(`handlerInput: ${handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withShouldEndSession(false)
.getResponse()}`);
resolve(handlerInput.responseBuilder.speak(speechOutput)
.reprompt(repromtText)
.withShouldEndSession(false)
.getResponse());
})
.catch((error) => {
console.log(`Error in SetDefaultLocationIntent promise: ${error}`);
reject(error);
});
});
}
});
}
},
};
Finally solved the problem: It was merely a promise issue I wasn't handling properly , I had to wrap everything in the else statement in a promise and this is how I restructured the last else statement to get the desired result.
else {
return new Promise((resolve, reject) => {
let params = '';
let lookupFunc = '';
let placeNameLookup = '';
if (zipcode.length > 0 && zipCodeValidator(zipcode)) {
params = zipcode;
lookupFunc = apiCalls.zipcodeLookup;
}else {
if (state.length === 0) {
params = city;
placeNameLookup = city;
}else{
params = `${city}+${state}`;
placeNameLookup = `${city} ${state}`;
}
lookupFunc = apiCalls.placeNameLookup;
}
lookupFunc (params, (error, result, duration) => {
if(error || result === null) {
// API Call failed or result is null
speechOutput = speech.getSpeechText('error2', false);
repromtText = speech.getSpeechText('reprompt3', false);
resolove(handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse());
}else if (Object.keys(result).length === 0) {
// Returned an empty result
if (zipcode.length > 0) {
// was zipcode
let speechObject = speech.getSpeechObject('setdefaultloc4');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
}else{
// wasn't zipcode
let speechObject = speech.getSpeechObject('setdefaultloc3');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
}
resolve(handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(repromtText)
.withSimpleCard(cardTitle, speechOutput)
.withShouldEndSession(false)
.getResponse());
}else {
// Api Call successfull with result objects length > 0
handlerInput.attributesManager.getPersistentAttributes()
.then((attributes) => {
const defaultLoc = {
name: result.name,
lat: result.lat,
lon: result.lon
};
const userId = handlerInput.requestEnvelope.context.System.user.userId;
attributes['defaultLoc'] = defaultLoc;
debugLog("Writing attributes to DynamoDB: " + userId + ", " + "defaultlocation: " + JSON.stringify(defaultLoc));
handlerInput.attributesManager.setSessionAttributes(attributes);
handlerInput.attributesManager.setPersistentAttributes(attributes);
handlerInput.attributesManager.savePersistentAttributes();
let speechObject = speech.getSpeechObject('setdefaultloc22');
repromtText = speech.getSpeechText('reprompt3', false);
speechOutput = util.format(speechObject.text, zipcode);
debugLog(`SpeechOutput After saving user location: ${speechOutput}`);
debugLog(`handlerInput: ${handlerInput.responseBuilder}`);
resolve(handlerInput.responseBuilder.speak(speechOutput)
.reprompt(repromtText)
.withShouldEndSession(false)
.getResponse());
})
.catch((error) => {
console.log(`Error in SetDefaultLocationIntent promise: ${error}`);
reject(error);
});
}
});
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.