Как подключить API REST по скилу алекса? - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь подключить api rest к навыку alexa. Я использовал alexa-nodejsfactskill в качестве базы. То, что я хотел бы получить, когда я вызываю намерения, - это услышать название из файла json. Это мой код

Когда я запускаю его, она говорит, что возникла проблема с вызовом навыка. Я работаю на платформе amazon dev, а не локально с установленным nodejs. Я думаю, что код возвращает нулевое значение, когда он пытается вызвать текст из JSON.

/ * eslint-disable func-names / / eslint-disable no-console * /

var https = require('https');
const Alexa = require('ask-sdk');

const GetNewFactHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'LaunchRequest'
            || (request.type === 'IntentRequest'
                && request.intent.name === 'nameofintents');
    },
    handle(handlerInput) {

        https.get('https://jsonplaceholder.typicode.com/todos/1', res => {
            res.setEncoding("utf8");
            let body = "";

            res.on("data", data => {
                body += data;
            });
            //On receiving the entire info from the API
            res.on("end", () => {
                body = JSON.parse(body);

                const speechOutput  = body.userId;
                 return handlerInput.responseBuilder
                  .speak(speechOutput)
                .getResponse();

            });
        });

        // const factArr = data;
        // const factIndex = Math.floor(Math.random() * factArr.length);
        // const randomFact = factArr[factIndex];
        // const speechOutput = GET_FACT_MESSAGE + randomFact;

        // return handlerInput.responseBuilder
        //   .speak(speechOutput)
        //   .withSimpleCard(SKILL_NAME, randomFact)
        //   .getResponse();
    },

};

const SKILL_NAME = 'nameskill';
const GET_FACT_MESSAGE = 'Here\'s your fact: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'bye!';

// const data = [
//   'A year on Mercury is just 88 days long.',
//   'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.',
// ];

const HelpHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'IntentRequest'
            && request.intent.name === 'AMAZON.HelpIntent';
    },
    handle(handlerInput) {
        return handlerInput.responseBuilder
            .speak(HELP_MESSAGE)
            .reprompt(HELP_REPROMPT)
            .getResponse();
    },
};

const ExitHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'IntentRequest'
            && (request.intent.name === 'AMAZON.CancelIntent'
                || request.intent.name === 'AMAZON.StopIntent');
    },
    handle(handlerInput) {
        return handlerInput.responseBuilder
            .speak(STOP_MESSAGE)
            .getResponse();
    },
};

const SessionEndedRequestHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'SessionEndedRequest';
    },
    handle(handlerInput) {
        console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

        return handlerInput.responseBuilder.getResponse();
    },
};

const ErrorHandler = {
    canHandle() {
        return true;
    },
    handle(handlerInput, error) {
        console.log(`Error handled: ${error.message}`);

        return handlerInput.responseBuilder
            .speak('Sorry, an error occurred.')
            .reprompt('Sorry, an error occurred.')
            .getResponse();
    },
};

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
    .addRequestHandlers(
        GetNewFactHandler,
        HelpHandler,
        ExitHandler,
        SessionEndedRequestHandler
    )
    .addErrorHandlers(ErrorHandler)
    .lambda();

Если я комментирую код в http.get и запускаю навык, два предложения воспроизводятся правильно. Спасибо вам за помощь.

1 Ответ

0 голосов
/ 14 января 2019

Вы вызываете асинхронную функцию изнутри функции синхронизации, поэтому она завершается до завершения вызова API.

const GetNewFactHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest'
    || (request.type === 'IntentRequest'
    && request.intent.name === 'nameofintents');
  },
  async handle(handlerInput) {
    let response = await new Promise(function(resolve, reject){
      https.get('https://jsonplaceholder.typicode.com/todos/1', res => {
        res.setEncoding("utf8");
        let body = "";

        res.on("data", data => {
          body += data;
        });

        response.on('end', () => {
          resolve(JSON.parse(body));
        });

        response.on('error', (error) => {
          reject(error);
        });
      });
    })

    return handlerInput.responseBuilder
    .speak(response.userId)
    .getResponse();
  }
}

В идеале вы можете переместить функцию выхода наружу, но это сработает.

Очень важно понять, как работают ожидающие / обещания для NodeJS, поэтому это поможет вам выполнять больше асинхронной работы.

...