You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Google Actions的Firebase函数调用第三方Rest API的异步问题

解决Firebase函数未等待API调用完成就终止的问题

你的问题根源在于Dialogflow的Intent处理函数没有返回异步操作的Promise,导致Firebase函数在第三方API请求完成前就提前终止,进而Google Actions收不到响应。另外针对老版本Node.js不支持async/await的情况,我们可以用Promise链式调用来完美解决,具体修改方案如下:

1. 让Intent处理函数返回Promise链

原来的代码中,你调用了callApi(param1).then(...)但没有将这个Promise返回给Dialogflow,导致函数执行完同步代码就直接结束了。只需要修改Intent处理逻辑,返回整个Promise链即可:

app.intent('my_intent_1', (conv, {param1}) => {
  // 关键:返回这个Promise链,让Dialogflow等待异步操作完成
  return callApi(param1)
    .then((output) => {
      console.log(output);
      conv.close(`I found ${output.length} items!`);
    })
    .catch(() => {
      conv.close('Error occurred while trying to get vehicles. Please try again later.');
    });
});

2. 完善callApi的Promise错误处理

确保callApi函数在所有异常场景下都正确触发reject,避免Promise处于pending状态:

function callApi (param1) {
  return new Promise((resolve, reject) => {
    let path = '/api/' + encodeURIComponent(param1);
    console.log('API Request: ' + host + path);

    http.get({host: host, path: path}, (res) => {
      // 新增:检查HTTP响应状态码,非200直接触发错误
      if (res.statusCode !== 200) {
        reject(new Error(`API returned status code ${res.statusCode}`));
        return;
      }

      let body = '';
      res.on('data', (d) => {
        body += d;
      });

      res.on('end', () => {
        try {
          let response = JSON.parse(body);
          // 这里将API返回的需要数据复制到output,示例假设取response中的items
          let output = response.items || []; 
          console.log(`Received ${output.length} items`);
          resolve(output);
        } catch (parseError) {
          // 处理JSON解析失败的情况
          console.log(`Error parsing API response: ${parseError}`);
          reject(parseError);
        }
      });

      res.on('error', (error) => {
        console.log(`Error calling the API: ${error}`);
        reject(error); // 传递错误对象,而非空reject
      });
    });
  });
}

3. 可选:升级Node.js版本以支持async/await

如果你的Firebase项目允许升级Node.js版本,可以在项目根目录的package.json中指定更高版本(Firebase目前支持Node.js 14+),这样后续就可以用async/await简化代码:

{
  "engines": {
    "node": "14"
  }
}

升级后,Intent处理函数可以改成更简洁的写法:

app.intent('my_intent_1', async (conv, {param1}) => {
  try {
    const output = await callApi(param1);
    console.log(output);
    conv.close(`I found ${output.length} items!`);
  } catch (err) {
    conv.close('Error occurred while trying to get vehicles. Please try again later.');
  }
});

核心原理说明

Dialogflow的Fulfillment函数依赖Promise来追踪异步操作的完成状态。如果Intent处理函数不返回Promise,系统会默认同步执行完毕就终止函数,此时你的API请求还在后台运行,自然无法将结果返回给用户。返回Promise后,系统会等待Promise被resolve或reject后再结束函数,确保响应能正确发送。

内容的提问来源于stack exchange,提问作者under

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:57:51