question

salazarpresentys avatar image
salazarpresentys asked

Alexa sends the speechoutput before to get the Api response

Hi,


I am developing an Alexa Skill using nodeJS 10 and lambda function.

My skill has the following behaviour:

- I say a number and the skill's intent makes an Api call with this number, in order to get a json with some data.

- I build a speechoutput with a static phrase and with a value with is retrieve from the json.

what is the problem? I get the speechoutput before the Api call makes effect, i.e., I get a error because "cannot read a property of undefined".


is there some workaround in order to get the api response before the speechoutput woulb be sended?


It looks like the code is not able to process the api call code synchronously.


thanks in advance,

Pedro.

alexa skills kitlambdaapinode_jsnodejs
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

Jason@Amazon avatar image
Jason@Amazon answered

You're correct in that you need to make asynchronous calls when requesting data from external APIs. Check out the following blog post for hints and tips on implementing this:

https://developer.amazon.com/blogs/alexa/post/28368692-a0b9-4579-b129-e6793bef7848/alexa-skill-recipe-update-making-http-requests-to-get-data-from-an-external-api-using-the-ask-software-development-kit-for-node-js-version-2

2 comments
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

thanks a lot, Jason!

0 Likes 0 ·

I would like to share how I have solved this, finally! (In order to help anyone)

In your intent:

const myHandler= {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'IntentRequest' 
        && request.intent.name === 'myHandlerIntent';
    },
    async handle(handlerInput) {
        var input = handlerInput.requestEnvelope;
        var number = input.request.intent.slots.numero.value;
        const response = await httpGet(number);

And the method httpGet()

function httpGet() {
    const HTTPS = require('https');
    try {
        return new Promise(((resolve, reject) => {
            var options = {
                host: "your endpoint",
                port: 443,
                path: "your path",
                method: 'GET',
            };
            const request = HTTPS.request(options, (response) => {
                response.setEncoding('utf8');
                let returnData = '';
                response.on('data', (chunk) => {
                    returnData += chunk;
                });
                response.on('end', () => {
                    resolve(JSON.parse(returnData));
                });
                response.on('error', (error) => {
                    reject(error);
                });
            });
            request.end();
        }));
    }
    catch (error) {
        console.log(error)
        return null;
    }
}


Hope this can be helpful

1 Like 1 ·