Hi I am implementing this https://github.com/alexa-labs/skill-sample-nodejs-level-up-riddles this example of isp and here is the code
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require('ask-sdk-core');
const RIDDLES = require("./riddle_objects");
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = "Welcome to Level Up Riddles! Before we get started, I need a few pieces of information."
+ " What is your name and favorite color?"
+ " How many riddles would you like to play with?"
+ " Would you like to start with easy, medium, or hard riddles?";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Level Up Riddles', speechText)
.getResponse();
},
};
const PlayGameIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'PlayGameIntent';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
const request = handlerInput.requestEnvelope.request;
// Get the level the customer selected: 'easy', 'med', 'hard'
sessionAttributes.currentLevel = request.intent.slots.level.value;
// Store the slot values for name and color
if (request.intent.slots.name.value) {
sessionAttributes.name = request.intent.slots.name.value;
}
if (request.intent.slots.color.value) {
sessionAttributes.color = request.intent.slots.color.value;
}
// Check if the slot value for riddleNum is filled and <5, otherwise default to 5
const riddleNum = request.intent.slots.riddleNum.value;
if (riddleNum) {
sessionAttributes.totalRids = riddleNum <= 5 ? riddleNum : 5;
} else {
sessionAttributes.totalRids = 5;
}
// Reset variables to 0 to start the new game
sessionAttributes.correctCount = 0;
sessionAttributes.currentIndex = 0;
sessionAttributes.currentHintIndex = 0;
// Get the first riddle according to that level
sessionAttributes.currentRiddle = RIDDLES.LEVELS[sessionAttributes.currentLevel][sessionAttributes.currentIndex];
sessionAttributes.speechText = "Lets play with "
+ sessionAttributes.currentLevel + " riddles! "
+ " First riddle: " + sessionAttributes.currentRiddle.question;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
return handlerInput.responseBuilder
.speak(sessionAttributes.speechText)
.reprompt(sessionAttributes.speechText)
.withSimpleCard('Level Up Riddles', sessionAttributes.speechText)
.getResponse();
}
};
const AnswerRiddleIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AnswerRiddleIntent';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
console.log(JSON.stringify(handlerInput.requestEnvelope.request.intent.slots));
// Determine if the customer said the correct answer for the current riddle
const spokenAnswer = handlerInput.requestEnvelope.request.intent.slots.answer.value;
sessionAttributes.speechText = "";
if (spokenAnswer === sessionAttributes.currentRiddle.answer) {
sessionAttributes.speechText += sessionAttributes.currentRiddle.answer + " is correct! You got it right! "
sessionAttributes.correctCount += 1;
sessionAttributes.correct = "Correct! ";
} else {
sessionAttributes.speechText += "Oops, that was wrong. The correct answer is " + sessionAttributes.currentRiddle.answer + ". ";
sessionAttributes.correct = "Incorrect! ";
}
// Move on to the next question
sessionAttributes.currentIndex += 1;
// If the customer has gone through all riddles, report the score
if (sessionAttributes.currentIndex === sessionAttributes.totalRids) {
sessionAttributes.speechText +=
"You have completed all of the riddles on this level! "
+ "Your correct answer count is "
+ sessionAttributes.correctCount
+ ". To play another level, say easy, medium, or hard. ";
// Reset variables to start a new game
sessionAttributes.currentLevel = "";
sessionAttributes.currentRiddle = {};
sessionAttributes.currentIndex = 0;
sessionAttributes.totalRids = 5;
} else {
sessionAttributes.currentRiddle = RIDDLES.LEVELS[sessionAttributes.currentLevel][sessionAttributes.currentIndex];
sessionAttributes.speechText += "Next riddle: " + sessionAttributes.currentRiddle.question;
}
// Reset hint index for the new question
sessionAttributes.currentHintIndex = 0;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
return handlerInput.responseBuilder
.speak(sessionAttributes.speechText)
.reprompt(sessionAttributes.speechText)
.withSimpleCard('Level Up Riddles', sessionAttributes.speechText)
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speechText = "I will give you 5 riddles. Would you like to start with easy, medium, or hard riddles?"
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Level Up Riddles', 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');
},
handle(handlerInput) {
const speechText = 'Goodbye!';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Level Up Riddles', speechText)
.getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
console.log("Error in request " + JSON.stringify(handlerInput.requestEnvelope.request));
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. Please say again.')
.reprompt('Sorry, I can\'t understand the command. Please say again.')
.getResponse();
}
};
//----------------------------------------------------------------------
//----------------------------ISP HANDLERS------------------------------
//----------------------------------------------------------------------
const HintIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'HintIntent';
},
handle(handlerInput) {
const locale = handlerInput.requestEnvelope.request.locale;
const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
// Determine if the customer has purchased the hint_pack
return ms.getInSkillProducts(locale).then(function(res) {
var product = res.inSkillProducts.filter(record => record.referenceName === 'hint_pack');
if (isEntitled(product)) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
const index = sessionAttributes.currentHintIndex;
// Read all hints the customer has asked for thus far
let speechText = "Okay, here are your hints: ";
let i = 0;
while (i <= index) {
speechText += sessionAttributes.currentRiddle.hints[i] + ", ";
i++;
}
speechText += ". Here is your question again: "
+ sessionAttributes.currentRiddle.question;
// Update the current hint index, maximum of 3 hints per riddle
sessionAttributes.currentHintIndex = index === 2 ? 2 : (index + 1);
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(sessionAttributes.currentRiddle.question)
.withSimpleCard('Level Up Riddles', speechText)
.getResponse();
} else {
const upsellMessage = "You don't currently own the hint pack. Want to learn more about it?";
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.SendRequest',
'name': 'Upsell',
'payload': {
'InSkillProduct': {
'productId': product[0].productId
},
'upsellMessage': upsellMessage
},
'token': 'correlationToken'
})
.getResponse();
}
});
}
};
const BuyIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
handlerInput.requestEnvelope.request.intent.name === 'BuyIntent';
},
handle(handlerInput) {
// Inform the user about what products are available for purchase
const locale = handlerInput.requestEnvelope.request.locale;
const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
return ms.getInSkillProducts(locale).then(function(res) {
let product = res.inSkillProducts.filter(record => record.referenceName === "hint_pack");
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.SendRequest',
'name': 'Buy',
'payload': {
'InSkillProduct': {
'productId': product[0].productId
}
},
'token': 'correlationToken'
})
.getResponse();
});
}
};
const UpsellResponseHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "Connections.Response" &&
handlerInput.requestEnvelope.request.name === "Upsell";
},
handle(handlerInput) {
if (handlerInput.requestEnvelope.request.status.code === 200) {
let speechOutput = "";
let reprompt = "";
if (handlerInput.requestEnvelope.request.payload.purchaseResult === 'ACCEPTED') {
speechOutput = "You can now ask for hints in your game! To get a hint, say, i want a hint. ";
reprompt = "Let's play a new game with hints! Would you like to start with easy, medium, or hard riddles?";
} else if (handlerInput.requestEnvelope.request.payload.purchaseResult === 'DECLINED') {
speechOutput = "Okay. I can't offer you any hints at this time. ";
reprompt = "Let's play a game. Would you like to start with easy, medium, or hard riddles?";
}
return handlerInput.responseBuilder
.speak(speechOutput + reprompt)
.reprompt(reprompt)
.getResponse();
} else {
// Something has failed with the connection.
console.log('Connections.Response indicated failure. error:' + handlerInput.requestEnvelope.request.status.message);
return handlerInput.responseBuilder
.speak("There was an error handling your purchase request. Please try again or contact us for help.")
.getResponse();
}
}
};
const BuyResponseHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "Connections.Response" &&
handlerInput.requestEnvelope.request.name === "Buy";
},
handle(handlerInput) {
const locale = handlerInput.requestEnvelope.request.locale;
const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
const productId = handlerInput.requestEnvelope.request.payload.productId;
return ms.getInSkillProducts(locale).then(function(res) {
let product = res.inSkillProducts.filter(record => record.productId === productId);
let speechOutput = "";
let reprompt = "";
if (handlerInput.requestEnvelope.request.status.code === 200) {
if (handlerInput.requestEnvelope.request.payload.purchaseResult === 'ACCEPTED') {
speechOutput = "You can now ask for hints in your game! To get a hint, say, i want a hint. ";
reprompt = "Let's play a new game with hints! Would you like to start with easy, medium, or hard riddles?";
} else if (handlerInput.requestEnvelope.request.payload.purchaseResult === 'DECLINED') {
speechOutput = "Thanks for your interest in the " + product[0].name + ". ";
reprompt = "Let's play a game. Would you like to start with easy, medium, or hard riddles?";
}
return handlerInput.responseBuilder
.speak(speechOutput + reprompt)
.reprompt(reprompt)
.getResponse();
} else {
// Something has failed with the connection.
console.log('Connections.Response indicated failure. error:' + handlerInput.requestEnvelope.request.status.message);
return handlerInput.responseBuilder
.speak("There was an error handling your purchase request. Please try again or contact us for help.")
.getResponse();
}
});
}
};
function isProduct(product) {
return product && product.length > 0;
}
function isEntitled(product) {
return isProduct(product) && product[0].entitled === 'ENTITLED';
}
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
PlayGameIntentHandler,
AnswerRiddleIntentHandler,
HelpIntentHandler,
HintIntentHandler,
BuyIntentHandler,
UpsellResponseHandler,
BuyResponseHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler
)
.withApiClient(new Alexa.DefaultApiClient())
.addErrorHandlers(ErrorHandler)
.lambda();
and here is the debugging code
{
"header": {
"namespace": "SkillDebugger",
"name": "CaptureDebuggingInfo",
"messageId": "b0d0c06d-dfcc-4447-9f13-13de78f49541"
},
"payload": {
"skillId": "amzn1.ask.skill.48327986-40a1-4ec1-8392-eb01bf090af7",
"timestamp": "2019-09-14T17:41:00.109Z",
"dialogRequestId": "877f3888-a770-41aa-85e4-02a6d118ad5e",
"skillRequestId": "amzn1.echo-api.request.3e7ad94e-1cae-4a9d-951c-53ba7eb28c8a",
"type": "SkillExecutionInfo",
"content": {
"invocationRequest": {
"endpoint": "arn:aws:lambda:us-east-1:376994955544:function:48327986-40a1-4ec1-8392-eb01bf090af7:Release_0",
"body": {
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.ac3e9d5f-0a63-45bc-ba52-d2b111a9ebd5",
"application": {
"applicationId": "amzn1.ask.skill.48327986-40a1-4ec1-8392-eb01bf090af7"
},
"user": {
"userId": "amzn1.ask.account.AGQPSJG646PB5IENG35DQC77L4OUIUFB6WURBMYQ2ATWZD4N2ATIYGLA5QIRSHQJEY4KKUEQYIYIHJGFE444GXMLL6VK3DROCZN43DAB33D6QN2OOAECDXQKUEJCCLWZVBGKYQCZYWQTED3Z56UEILVMIJAQ7CDRUEYLDIYZL5HB6BVM2A5AVUMNKE4T3WCLEQFRZ222QZKE2QI"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.ask.skill.48327986-40a1-4ec1-8392-eb01bf090af7"
},
"user": {
"userId": "amzn1.ask.account.AGQPSJG646PB5IENG35DQC77L4OUIUFB6WURBMYQ2ATWZD4N2ATIYGLA5QIRSHQJEY4KKUEQYIYIHJGFE444GXMLL6VK3DROCZN43DAB33D6QN2OOAECDXQKUEJCCLWZVBGKYQCZYWQTED3Z56UEILVMIJAQ7CDRUEYLDIYZL5HB6BVM2A5AVUMNKE4T3WCLEQFRZ222QZKE2QI"
},
"device": {
"deviceId": "amzn1.ask.device.AFO224KLCPL4LORCN7PZ3FTF3DRAHXPU3JIWVZ5UTQEJWYJUFSXIOK4XRD4M64CFW7JYDLBBEUND6VD7BU75VTU4TDGT7I67BI4MDN5OCEXTIGOWD6YYPF4JERWXXX6BHTADDNG66BG6DJOFYCDQOTJ45W37WCBYUBDMO32KGFZZUFBTMN4U6",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.eu.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLjQ4MzI3OTg2LTQwYTEtNGVjMS04MzkyLWViMDFiZjA5MGFmNyIsImV4cCI6MTU2ODQ4MzE2MCwiaWF0IjoxNTY4NDgyODYwLCJuYmYiOjE1Njg0ODI4NjAsInByaXZhdGVDbGFpbXMiOnsiY29udGV4dCI6IkFBQUFBQUFBQVFCcDY0dXd0SlpXTmdwdTdid3ZWN05hS3dFQUFBQUFBQUNacmRRbGlVd0RmbzkyWlVpQ1FrbWtGSkR4blRTNm8ya2JEa3RoTzNCSkxrbmNaejlJOUpHaTNHS3NSbzdSK1lBVmNKckVHY0l5d0wybGllWkVqRk1CVXd1cVdMeTk3N1h1dDFnTDhYNnBhMjB1dkFtSFpzd2J6MklIUTN1SlVwSEorMUNlSnlva2szalRLdE9tenNML0JCRlpLSHhUZGVyM0Z0U1AyQ3Y1c08xQWFrOXlnTkQ1L0JZOGhEQUYzZTdGNDF0ZEFURXptUWt1Q0s5R1dQdU1IdHE4eFFlaGdRZWJHV3lTQWNZODZta1U2U2lpM3JVR2RJOUVPY3h3cE9WbHRQbG4wSVJXTWg4eU9Wb0Q0M09QVi84RGxZbXc3ZjF0a0VqTDJMVlBQWWdkVmppaXNBd3FuYmpjWWQzTFJxR0ZkazI4RFRMdWZyNG9Fb2tzRExHdkZRd1hOc1c0YitmWWgzRnhrWnhXd25UZUkyUjVRQUhzVTVTTjBnMTZvZTRQRS93T085akVzb0tSNFE9PSIsImNvbnNlbnRUb2tlbiI6bnVsbCwiZGV2aWNlSWQiOiJhbXpuMS5hc2suZGV2aWNlLkFGTzIyNEtMQ1BMNExPUkNON1BaM0ZURjNEUkFIWFBVM0pJV1ZaNVVUUUVKV1lKVUZTWElPSzRYUkQ0TTY0Q0ZXN0pZRExCQkVVTkQ2VkQ3QlU3NVZUVTRUREdUN0k2N0JJNE1ETjVPQ0VYVElHT1dENllZUEY0SkVSV1hYWDZCSFRBRERORzY2Qkc2REpPRllDRFFPVEo0NVczN1dDQllVQkRNTzMyS0dGWlpVRkJUTU40VTYiLCJ1c2VySWQiOiJhbXpuMS5hc2suYWNjb3VudC5BR1FQU0pHNjQ2UEI1SUVORzM1RFFDNzdMNE9VSVVGQjZXVVJCTVlRMkFUV1pENE4yQVRJWUdMQTVRSVJTSFFKRVk0S0tVRVFZSVlJSEpHRkU0NDRHWE1MTDZWSzNEUk9DWk40M0RBQjMzRDZRTjJPT0FFQ0RYUUtVRUpDQ0xXWlZCR0tZUUNaWVdRVEVEM1o1NlVFSUxWTUlKQVE3Q0RSVUVZTERJWVpMNUhCNkJWTTJBNUFWVU1OS0U0VDNXQ0xFUUZSWjIyMlFaS0UyUUkifX0.fd1lu3rIm9ImuBiP_2uDL7mqTP9KXcDDXPo7tLs8ouJ0wW9PbEB_SusSJiZ6hjoJci2zJZcT7Q4wyVIyZYMw5DTZGO097tSLM2PjliNN5hOvtYJmYI20KQyYYarzQuPTbzg8L_SPmr2Tl_lDBbpMUwcYDzggKGlU84qUS9LUa3AVavK9bKBeqymSHxyWwEXuil1kw3DJp4MwVL7GAYsA5gQbkC9pFyQm3goWKZg51_KZ5ev3GUAGjaeZbfMNxglQDdX4sIeBqUqTmwYpGRIRjKMvhhnd0J9WKVU9QGr0KqYtXv2SLpEoJ6Qdmf8NQS2FReP9shdw142InK7ySkWIjw"
},
"Viewport": {
"experiences": [
{
"arcMinuteWidth": 246,
"arcMinuteHeight": 144,
"canRotate": false,
"canResize": false
}
],
"shape": "RECTANGLE",
"pixelWidth": 1024,
"pixelHeight": 600,
"dpi": 160,
"currentPixelWidth": 1024,
"currentPixelHeight": 600,
"touch": [
"SINGLE"
],
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
}
}
},
"request": {
"type": "Connections.Response",
"requestId": "amzn1.echo-api.request.3e7ad94e-1cae-4a9d-951c-53ba7eb28c8a",
"timestamp": "2019-09-14T17:41:00Z",
"locale": "en-US",
"status": {
"code": "200",
"message": "OK"
},
"name": "Upsell",
"payload": {
"purchaseResult": "ERROR",
"productId": "amzn1.adg.product.214ce17e-f466-4b08-9afa-215954c297ac",
"message": "Upsell was not presented."
},
"token": "correlationToken"
}
}
},
"invocationResponse": {
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>There was an error handling your purchase request. Please try again or contact us for help.</speak>"
},
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-node/2.7.0 Node/v8.10.0"
}
},
"metrics": {
"skillExecutionTimeInMilliseconds": 85
}
}
}
}
And I am getting this error in Alexa test tab as far as I know it is else part from my code in index.js
"There was an error handling your purchase request. Please try again or contact us for help."
By the way I am making us skill and i don't live in us is that a problem?
Thnks for the reply :)