简体   繁体   English

如何使用Alexa技能连接API REST?

[英]How to connect API REST on alexa skill?

I'm trying to connect api rest to an alexa skill. 我正在尝试将api rest连接到alexa技能。 I used alexa-nodejsfactskill as a base. 我使用alexa-nodejsfactskill作为基础。 What I would like to get when I call intents is to hear the title from the json file. 当我调用意图时,我想得到的是从json文件中听到标题。 This is my code. 这是我的代码。

When I run it, she says there was a problem calling up the skill. 当我运行它时,她说调用该技能存在问题。 I'm working on the amazon dev platform and not in local with nodejs installed. 我正在亚马逊开发平台上工作,而不是在安装了nodejs的本地工作。 I think tht The code returns null value when it tries to call the text from the json. 我认为代码在尝试从json调用文本时返回null值。

/* eslint-disable func-names / / eslint-disable no-console */ / *禁用eslint功能名称//禁用无控制台eslint * /

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();

If I comment the code in http.get and I launch the skill, the two sentences are correctly reproduced. 如果我注释了http.get中的代码并启动了该技能,则正确地复制了这两个句子。 Thank you for the help. 感谢您的帮助。

You are calling an async function from inside a sync function, therefore it finishes before the API call gets done. 您正在从同步函数内部调用异步函数,因此它在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();
  }
}

Ideally, you can move the function of the get outside, but that will work. 理想情况下,您可以将get的功能移到外部,但这将起作用。

It's really important to understand how await/promises work for NodeJS so it will help you to do more async work. 了解NodeJS的等待/承诺工作方式非常重要,这样可以帮助您完成更多异步工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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