0

我正在尝试进行自己的 google 操作,并且我想调用外部 api 来获得响应。

这是我的代码:

const { conversation } = require('@assistant/conversation');
const functions = require('firebase-functions');
const app = conversation({debug:true});
const https = require('https');

app.handle('Tester', conv => {
  // Implement your code here
  conv.add("ok it works");
});

app.handle('Tester2', conv => {
  // Implement your code here
  let url = 'https://jsonplaceholder.typicode.com/users?_limit=2';
  //const url = "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22";
  
  http_req(url).then((message)=> {
    console.log(message[0].name);
      conv.add(message[0].name);
    //return Promise.resolve();
  });
});

function http_req(url) {
  return new Promise((resolve, reject) => {
      https.get(url, function(resp) {
          var json = "";
          resp.on("data", function(chunk) {
              //console.log("received JSON response: " + chunk);
              json += chunk;
          });

          resp.on("end", function() {
              let jsonData = JSON.parse(json);
                                console.log(jsonData[0].name);
                resolve(jsonData);
          });
      }).on("error", (err) => {
          reject("Error: " + err.message);
      });
  });
}

exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);

日志: 在此处输入图像描述

错误文字:

Error: Response has already been sent. Is this being used in an async call that was not returned as a promise to the intent handler?

问题是助手不会说 conv.add(message[0].name); (显然它是有价值的)

提前致谢!

4

1 回答 1

0

感谢 reddit 用户 https://www.reddit.com/r/GoogleAssistantDev/comments/lia5r4/make_http_get_from_fulfillment_in_nodejs/gn23hi3?utm_source=share&utm_medium=web2x&context=3

此错误消息告诉您几乎所有您需要知道的信息!您对 con.add() 的调用确实在异步调用中使用(回调链接到您从 http_req 创建的 Promise),并且您确实没有返回该 Promise。

这是正在发生的事情:

Google 调用您的“Tester2”处理程序

您通过 http_req 启动异步 HTTP 请求,封装在 Promise 中

您的函数在 HTTP 请求之前完成

Google 发现您没有从处理程序返回任何内容并假设您已完成,因此它发送响应

HTTP 请求完成并且它的 Promise 解析,调用 then() 函数附加的代码

这里的简单解决方案是返回由您的 http_req(...).then(...) 代码创建的 Promise,因此 Google 会知道您还没有完成,它应该等待该 Promise 解决之前发送响应。

如果您可以使用 async/await 它会变得更清晰:

app.handle('Tester2', async conv => {
  // Implement your code here
  let url = 'https://jsonplaceholder.typicode.com/users?_limit=2';
  //const url = "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22";

  const message = await http_req(url);
  console.log(message[0].name);
  conv.add(message[0].name);
});
于 2021-02-12T15:15:16.510 回答