首页 > 解决方案 > 在 SDK v2 上使用 Alexa 和 Lambda 的 HTTP 请求,如何使其工作?

问题描述

我正在使用亚马逊提供的 ASK SDK v2 来为 Alexa 制作技能,但我面临一个架构问题:

首先,HTTP 请求就像一个魅力,但是当且仅当我的 HTTP 请求完成时我想返回语音响应,但我什至不知道这是否可能,因为“句柄”函数应该返回一些东西(看评论):

const MyIntentHandler = {

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

    var options = {
      host: 'http://foo.com',
      port: 80,
      path: '/mypath',
      method: 'GET'
    };

    var req = http.request(options, function(result){
      result.on("end", function(){
        //I would like to return speak here like that :
        //return handlerInput.responseBuilder.speak("It works").withSimpleCard("MyTestApp", "It works").getResponse()
      })
    });
    req.end();
    //And I would like to remove this line to manage response in result.on("end", function(){}) above
    return handlerInput.responseBuilder.speak("It works").withSimpleCard("MyTestApp", "It works").getResponse();
  },
};

任何想法来处理这个?

标签: node.jsaws-lambdahttprequestalexaalexa-skills-kit

解决方案


我找到了官方的制作方法:

1)创建一个管理http请求并返回promise的新函数:

function httpGet(options) {
  return new Promise(((resolve, reject) => {

    const request = http.request(options, (response) => {
      response.setEncoding('utf8');
      let returnData = '';

      if (response.statusCode < 200 || response.statusCode >= 300) {
        return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
      }

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

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

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

2) 在 Intent 中,返回一个调用 httpGet 函数的承诺:

const MyIntentHandler = {

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

    var options = {
      host: 'http://foo.com',
      port: 80,
      path: '/mypath',
      method: 'GET'
    };

    return new Promise((resolve, reject) => {
     httpGet(options).then((response) => {
       resolve(handlerInput.responseBuilder.speak("It is done.").getResponse());
     }).catch((error) => {
        resolve(handlerInput.responseBuilder.speak('Thor is not available at the moment. Please try again later or contact your administrator.')
        .getResponse());
      });
    });
  },
};

这是正确执行此操作的方法。我的示例基于alexa petmatch sample


推荐阅读