【问题标题】:Can't make a API request in DialogFlow and actions-on-google. No response has been set无法在 DialogFlow 和 actions-on-google 中发出 API 请求。未设置响应
【发布时间】:2019-03-11 20:42:22
【问题描述】:

我正在尝试使用 actions-on-google 和 dialogflow 发出 API 请求,但在调用解决后,我猜 conv.ask 不算作最终响应。

我的代码:

const functions = require('firebase-functions');
const {dialogflow,Permission} = require('actions-on-google');
const request = require('request');
const rp = require('request-promise-native');
const fetch = require('node-fetch');
 
const app = dialogflow();

const API_URL = "https://pokeapi.co/api/v2/pokemon/1/";

app.intent('CriarLista - produtos - yes', (conv) => {
    conv.data.requestedPermission = 'DEVICE_PRECISE_LOCATION';
    return conv.ask(new Permission({
        context: 'Para te localizar',
        permissions: conv.data.requestedPermission,
    }));
});
app.intent('CriarLista - location_permission', (conv, params, permissionGranted) => {
    if (permissionGranted) {
        const {requestedPermission} = conv.data;
        if (requestedPermission === 'DEVICE_PRECISE_LOCATION') {
        
            const {coordinates} = conv.device.location;
            
            if (coordinates) {
                let lat = coordinates.latitude;
                let long = coordinates.longitude;

                fetch(API_URL).then(function(res) {
                    let data = res.json();
                }).then(function(data) {
                    conv.ask('Test');
                }).catch(function(err) {
                    console.log(err);
                });
                
            } else {
                return conv.close('Sorry, I could not figure out where you are.');
            }
        }
    } else {
        return conv.close('Sorry, permission denied.');
    }
});
 
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

错误: 谷歌上的行动响应:

{
  "responseMetadata": {
    "status": {
      "code": 10,
      "message": "Failed to parse Dialogflow response into AppResponse because of empty speech response",
      "details": [
        {
          "@type": "type.googleapis.com/google.protobuf.Value",
          "value": "{\"id\":\"74f26d40-869c-4ccb-9d75-1473f42e9aee\",\"timestamp\":\"2018-10-06T15:33:01.004Z\",\"lang\":\"pt-br\",\"result\":{},\"status\":{\"code\":206,\"errorType\":\"partial_content\",\"errorDetails\":\"Webhook call failed. Error: 500 Internal Server Error\"},\"sessionId\":\"ABwppHEUqmeurK1aqRe3QRDCo2BrPyZOu4cI447He8ZgA882v72AICpeqPCyzHEA6QCKTeo4cn4CzIZ9ACozv15L\"}"
        }
      ]
    }
  }
}

Firebase 控制台:

FetchError: request to https://pokeapi.co/api/v2/pokemon/1/ failed, reason: getaddrinfo EAI_AGAIN pokeapi.co:443

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

说我需要返回一个promise,我猜是一个“resolve”方法,但我什至尝试做出我的promise,但它不起作用,fetch方法中的“then”已经是一个promise返回的resolve方法.我试过 node-fetch、request、request-promise-native..

在部署到 firebase 后,仅在 fetch 块外运行 conv.ask 可以正常工作。

在 DialogFlow/actions-on-google 环境中进行外部请求有正确的方法吗?

【问题讨论】:

  • 您是否在 Firebase 上使用 Blaze 计划?您需要有付费计划才能发出外部请求,例如 API 调用。
  • @Denis 不,我得到了它来提出请求,但我意识到我至少需要一个 Blaze 计划才能返回响应。谢谢!

标签: node.js firebase google-cloud-functions dialogflow-es actions-on-google


【解决方案1】:

您需要 return 承诺对象,以便 webhook 知道等到承诺完成。

由于 fetch() 已经返回了一个 Promise(就像它之后的所有 .then() 调用一样,因为这就是人们通常使用 Promise 的方式),你只需要返回那个 Promise。所以你可以把这条线改成

            return fetch(API_URL).then(function(res) {
                let data = res.json();
            }).then(function(data) {
                conv.ask('Test');
            }).catch(function(err) {
                console.log(err);
            });

【讨论】:

  • 我已经尝试使用 return Promise.resolve(),我该如何在 fetch 中做到这一点?
  • 只需返回 fetch() 已经返回的 Promise。我添加了一些示例代码。
猜你喜欢
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
  • 2019-07-08
  • 1970-01-01
相关资源
最近更新 更多