简体   繁体   中英

Alexa Trivia Skill

Good Morning

I have been coding Alexa skills for a while and i decided to make a Trivia Quiz, I coded it mainly in Javascript and used the Quiz Template to help me with a few modifications.

I have got all my Intents set up and the code is doing what I need, the final bit I need to do it populate an Array with data from an external API, I believe I have set up the API request correctly as i have used the same code before.

However when I run the skill it keeps flagging up saying there was an error populating the data, and when I look in the logs my API code isn't showing, have I done something wrong?

I hope you can have a look at what i have and see what i have done wrong, the questions are populated in my functions called populate data.

function populateData()
{   
    if(difficulty == "")
    {
        questions = [];
        var i =0;

        var options = {
            host: 'opentdb.com',
            port: 443,
            path: '/api.php?amount=50',
            method: 'GET'
        };

        var req = https.request(options, res => {
        res.setEncoding('utf8');
        var returnData = "";

        res.on('data', chunk => {
            returnData = returnData + chunk;
        });

        res.on('end', () => {
            // we have now received the raw return data in the returnData variable.
            // We can see it in the log output via:
            // console.log(JSON.stringify(returnData))
            // we may need to parse through it to extract the needed data

            console.log(JSON.stringify(returnData));

            for(i=0; i < 50; i++)
            {

            var question = JSON.parse(returnData).results[i].question;
            var answer1 = JSON.parse(returnData).results[i].correct_answer;
            var answer2 = JSON.parse(returnData).results[i].incorrect_answers[0];
            var answer3 = JSON.parse(returnData).results[i].incorrect_answers[1];
            var answer4 = JSON.parse(returnData).results[i].incorrect_answers[2];

            var qdata = '{"' + question + '":[' + '"' + answer1 + '","' + answer2 + '","' + answer3 + '","' + answer4 + '"]},';

            console.log(qdata);

            questions.push(qdata);

            }

        });

    });
    req.end();

    if(i == 50)
    {
        return true;
    }

    }
    else if(difficulty == "easy")
    {
        questions = [];
        var i =0;

        var options = {
            host: 'opentdb.com',
            port: 443,
            path: '/api.php?amount=50&difficulty=easy',
            method: 'GET'
        };

        var req = https.request(options, res => {
        res.setEncoding('utf8');
        var returnData = "";

        res.on('data', chunk => {
            returnData = returnData + chunk;
        });

        res.on('end', () => {
            // we have now received the raw return data in the returnData variable.
            // We can see it in the log output via:
            // console.log(JSON.stringify(returnData))
            // we may need to parse through it to extract the needed data

            console.log(JSON.stringify(returnData));

            for(i=0; i < 50; i++)
            {

            var question = JSON.parse(returnData).results[i].question;
            var answer1 = JSON.parse(returnData).results[i].correct_answer;
            var answer2 = JSON.parse(returnData).results[i].incorrect_answers[0];
            var answer3 = JSON.parse(returnData).results[i].incorrect_answers[1];
            var answer4 = JSON.parse(returnData).results[i].incorrect_answers[2];

            var qdata = '{"' + question + '":[' + '"' + answer1 + '","' + answer2 + '","' + answer3 + '","' + answer4 + '"]},';

            questions.push(qdata);

            }

        });

    });
    req.end();

    if(i == 50)
    {
        return true;
    }

    }
    else if(difficulty == "medium")
    {
        questions = [];
        var i=0;

        var options = {
            host: 'opentdb.com',
            port: 443,
            path: '/api.php?amount=50&difficulty=medium',
            method: 'GET'
        };

        var req = https.request(options, res => {
        res.setEncoding('utf8');
        var returnData = "";

        res.on('data', chunk => {
            returnData = returnData + chunk;
        });

        res.on('end', () => {
            // we have now received the raw return data in the returnData variable.
            // We can see it in the log output via:
            // console.log(JSON.stringify(returnData))
            // we may need to parse through it to extract the needed data

            console.log(JSON.stringify(returnData));

            for(i=0; i < 50; i++)
            {

            var question = JSON.parse(returnData).results[i].question;
            var answer1 = JSON.parse(returnData).results[i].correct_answer;
            var answer2 = JSON.parse(returnData).results[i].incorrect_answers[0];
            var answer3 = JSON.parse(returnData).results[i].incorrect_answers[1];
            var answer4 = JSON.parse(returnData).results[i].incorrect_answers[2];

            var qdata = '{"' + question + '":[' + '"' + answer1 + '","' + answer2 + '","' + answer3 + '","' + answer4 + '"]},';

            questions.push(qdata);

            }

        });

    });
    req.end();

    if(i == 50)
    {
        return true;
    }

    }
    else if(difficulty == "hard")
    {
        questions = [];
        var i=0;

        var options = {
            host: 'opentdb.com',
            port: 443,
            path: '/api.php?amount=50&difficulty=hard',
            method: 'GET'
        };

    var req = https.request(options, res => {
        res.setEncoding('utf8');
        var returnData = "";

        res.on('data', chunk => {
            returnData = returnData + chunk;
        });

        res.on('end', () => {
            // we have now received the raw return data in the returnData variable.
            // We can see it in the log output via:
            // console.log(JSON.stringify(returnData))
            // we may need to parse through it to extract the needed data

            console.log(JSON.stringify(returnData));

            for(i=0; i < 50; i++)
            {

            var question = JSON.parse(returnData).results[i].question;
            var answer1 = JSON.parse(returnData).results[i].correct_answer;
            var answer2 = JSON.parse(returnData).results[i].incorrect_answers[0];
            var answer3 = JSON.parse(returnData).results[i].incorrect_answers[1];
            var answer4 = JSON.parse(returnData).results[i].incorrect_answers[2];

            var qdata = '{"' + question + '":[' + '"' + answer1 + '","' + answer2 + '","' + answer3 + '","' + answer4 + '"]},';

            questions.push(qdata);

            }
        });

    });
    req.end();

    }

    if(i == 50)
    {
        return true;
    }
}

This function is called when the user asks to start quiz

function getWelcomeResponse(callback) 
{

var populated = populateData();

if(populated)
{
var sessionAttributes = {},
    speechOutput = "I will ask you " + GAME_LENGTH.toString()
        + " questions, try to get as many right as you can. Just say the number of the answer. Let's begin. ",
    shouldEndSession = false,

    gameQuestions = populateGameQuestions(),
    correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)), // Generate a random index for the correct answer, from 0 to 3
    roundAnswers = populateRoundAnswers(gameQuestions, 0, correctAnswerIndex),

    currentQuestionIndex = 0,
    spokenQuestion = Object.keys(questions[gameQuestions[currentQuestionIndex]])[0],
    repromptText = "Question 1. " + spokenQuestion + " ",

    i, j;

for (i = 0; i < ANSWER_COUNT; i++) {
    repromptText += (i+1).toString() + ". " + roundAnswers[i] + ". "
}
speechOutput += repromptText;
var sessionAttributes = {
    "speechOutput": repromptText,
    "repromptText": repromptText,
    "currentQuestionIndex": currentQuestionIndex,
    "correctAnswerIndex": correctAnswerIndex + 1,
    "questions": gameQuestions,
    "score": 0,
    "correctAnswerText":
        questions[gameQuestions[currentQuestionIndex]][Object.keys(questions[gameQuestions[currentQuestionIndex]])[0]][0]
};
callback(sessionAttributes,
    buildSpeechletResponse(CARD_TITLE, speechOutput, repromptText, shouldEndSession));
}
else
{
    callback(sessionAttributes,
    buildSpeechletResponseWithoutCard("There has been an error while populating data", "There has been an error while populating data", false));
}

}

Hope you can help me as i am pulling my hair out and can't see where i have gone wrong.

thanks

There's a lot going on here but from tracing through here it SEEMS what may be happening is a classic case of node.js callback timing issues - more specifically your Lambda function returning before your API calls are completed (you may also have some variable scoping issues - hard to tell from here).

If your response depends on the result of an API call you need to wait to return your response until that has completed. In your case I'd try passing the callback function through to your populateData method then building your response and calling the callback within res.on('end'...

I fixed the issue, thanks

I used a https.get request and then used Json.Parse to get the results, i have now added them to the array which i needed.

I also added a callback to make the other function work, and now it is working, thank you

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM