我有一个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_api_request函数,它将返回“ test:
function address_api_request (agent) {
agent.add('test');
}
答案 0 :(得分:0)
这里有两个问题。
第一个是,如果您使用的是Dialogflow的内置编辑器,则它是在幕后使用Firebase Cloud Functions。 Firebase Cloud Functions的默认级别不允许Google云端以外的网络访问。
您可以通过将项目升级到Firebase的Blaze Plan来解决此问题,该过程确实需要使用信用卡记录并按次计费,但是有免费层足以进行合理的测试,甚至正在生产中使用一些光。行动获得批准后,您就有资格获得可用于此目的的Google Cloud积分。
另一个问题是您有一个异步函数(http.get()
),但是您没有使用Promise来处理该函数,而是让handleRequest()
方法知道它需要等待返回结果前要解析的函数。如果您使用的是异步函数,则Dialogflow库要求您从函数中返回一个Promise。
您可以选择几种处理方式。首先,您可以将对http.get()
的调用包装为creating a new Promise object的一部分,并在end
处理程序中,按照指示发送消息,然后调用resolve
参数您需要在Promise处理程序中接受。但是,更简单的方法是使用诸如request-promise-native之类的库,该库为您包装了很多内容,并使您可以将结果作为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" );
});
}