Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Dialogflow Webhook中向对话返回API响应_Javascript_Firebase_Google Cloud Functions_Dialogflow Es - Fatal编程技术网

Javascript 如何在Dialogflow Webhook中向对话返回API响应

Javascript 如何在Dialogflow Webhook中向对话返回API响应,javascript,firebase,google-cloud-functions,dialogflow-es,Javascript,Firebase,Google Cloud Functions,Dialogflow Es,我有一个Dialogflow Webhook实现集成,它对我设置的API执行GET请求。但我似乎无法在对话中以文本形式获得API的响应 API确实接收http GET请求并返回状态代码为200的响应。 如果我在浏览器中执行相同的请求,结果如下: { "avmid": "1011GZ 18", "straat": "Snoekjesgracht", "postcode": "1011GZ", "stad": "AMSTERDAM", "provinciena

我有一个Dialogflow Webhook实现集成,它对我设置的API执行GET请求。但我似乎无法在对话中以文本形式获得API的响应

API确实接收http GET请求并返回状态代码为200的响应。 如果我在浏览器中执行相同的请求,结果如下:

{
    "avmid": "1011GZ 18",
    "straat": "Snoekjesgracht",
    "postcode": "1011GZ",
    "stad": "AMSTERDAM",
    "provincienaam": "Noord-Holland",
    "date": "2013-12-30",
    "koopsom": 199800,
    "koopsom2018q2": 333849
}
我试过好几种方法,但似乎都不能奏效。 这是我的JavaScript:

'use strict';

const http = require('http');

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  function address_api_request (agent) {

    let postcode = agent.parameters.zipcode;
    let housenumber = agent.parameters.housenumber;

    let avmid = postcode.toString()+'+'+housenumber.toString();
    let url = 'http://XXX.XXX.XXX.XXX:XX/api/1011GZ+18';


    var http = require('http');
    http.get(url, function(response) {

            var body = '';
            response.on('data', function(d) {
                body += d;
            });
            response.on('end', function() {

                var parsed = JSON.parse(body);
                agent.add(parsed.toString());
            });
        });
    }


  function welcome (agent) {
    agent.add(`Welcome to my agent!`);
    agent.add(agent.request_.body.queryResult.fulfillmentText);
  }

  function fallback (agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('company.woningwaarde-get-address-api', address_api_request);
  intentMap.set('Default Welcome Intent', welcome);
  intentMap.set('Default Fallback Intent', fallback);
  agent.handleRequest(intentMap);
});
意图是有效的,如果我用下面的代码替换address\u api\u request函数,它将返回“test:


这里有两个问题

首先,如果您使用的是Dialogflow的内置编辑器,那么它就是在幕后使用Firebase云功能。Firebase云功能的默认级别不允许在Google云之外进行网络访问

您可以通过将项目升级到Firebase来解决此问题,Firebase确实需要信用卡存档并收取每次使用的费用,但是有一个免费的层足以进行合理的测试,甚至可以在生产过程中进行少量使用。一旦您的操作获得批准,您将有资格获得谷歌云积分,这可能会导致可用于此目的

另一个问题是,您有一个异步函数(
http.get()
),但您没有使用承诺来处理该函数并让
handleRequest()
方法知道在返回结果之前需要等待函数解析。如果您使用的是异步函数,Dialogflow库要求您从函数返回承诺

对于如何处理这个问题,您有几个选择。首先,您可以将调用包装为http.get()作为
端处理程序的一部分,在
端处理程序中,按照指示发送消息,然后在Promise处理程序中调用需要接受的
resolve
参数。不过,更简单的方法是使用这样的库,它为您包装了大部分内容,并让您作为
then()的一部分获得结果
子句,您将在其中处理它

我尚未对其进行测试,但您的代码可能会如下所示:

function address_api_request (agent) {

  let postcode = agent.parameters.zipcode;
  let housenumber = agent.parameters.housenumber;

  let avmid = postcode.toString()+'+'+housenumber.toString();
  let url = 'http://XXX.XXX.XXX.XXX:XX/api/1011GZ+18';

  const rp = require('request-promise-native');
  var options = {
    uri: url,
    json: true
  };
  return rp( options )
    .then( body => {
      // Since json was set true above, it parses it for you
      // You wouldn't really want to send back the whole body
      agent.add( body );
    })
    .catch( err => {
      console.log('Problem with request', err );
      agent.add( "Uh oh, something went wrong" );
    });
}

感谢您精心准备的响应,但不幸的是,它不起作用。我已经有了一个Blaze计划,所以应该可以。正如我提到的,API正在接收一个请求并发送一个响应。问题在于,我无法将API的JSON响应返回到对话中。使用您的解决方案,API不会得到一个响应这可能与承诺有关吗?我需要在其他地方添加一些代码来处理吗?可能我的代码有错误-正如我所说,我没有测试它(我没有你的URL),但基于我使用的代码,它是有效的。我添加了一个catch块,您可以添加额外的调试来查看正在发生的事情,或者检查文档以确保不需要设置任何额外的内容。您不需要添加任何内容来处理返回的承诺,因为您使用的是
handleIntent()
。您不需要使用请求承诺,但如果您正在执行异步工作,则确实需要使用并返回承诺。
function address_api_request (agent) {

  let postcode = agent.parameters.zipcode;
  let housenumber = agent.parameters.housenumber;

  let avmid = postcode.toString()+'+'+housenumber.toString();
  let url = 'http://XXX.XXX.XXX.XXX:XX/api/1011GZ+18';

  const rp = require('request-promise-native');
  var options = {
    uri: url,
    json: true
  };
  return rp( options )
    .then( body => {
      // Since json was set true above, it parses it for you
      // You wouldn't really want to send back the whole body
      agent.add( body );
    })
    .catch( err => {
      console.log('Problem with request', err );
      agent.add( "Uh oh, something went wrong" );
    });
}