我正在尝试构建一个 Dialogflow 聊天机器人,它通过 Google Cloud Functions 从外部 API 获取数据,但不使用 Firebase。尽管进行了广泛的搜索,但我没有找到任何好的示例或模板;似乎所有可用的示例都使用 Firebase 函数。
我是一个新手程序员,不熟悉 Node.js、Promises 和所有那些花哨的东西,但我收集到即使没有 Firebase 也应该可以通过 Dialogflow 访问外部 API(我使用的是 Google Cloud 的付费版本)。
我尝试使用这个 Dialogflow 天气 API 示例创建我的谷歌云函数,这是我能找到的最接近我需要的东西,即使这也使用了 Firebase: https ://github.com/dialogflow/fulfillment-weather-nodejs /blob/master/functions/index.js#L72
问题是我的代码在“res.on('end'...”行附近的某个地方失败了,我不知道为什么。Google Cloud Stackdriver 日志只给出了相当不具信息性的消息“忽略来自已完成函数的异常",但没有告诉我异常是什么。
这是我的 index.js 代码的编辑版本:
'use strict';
const rpn = require('request-promise-native');
const http = require('http');
const hostAPI = 'my host API URL goes here';
const url = require('url');
const {WebhookClient} = require('dialogflow-fulfillment');
exports.myGoogleCloudSearch = (req, res) => {
const agent = new WebhookClient({request: req, response: res}); // Dialogflow agent
// These are logged in Google Cloud Functions
console.log('Dialogflow Request headers: ' + JSON.stringify(req.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(req.body));
// Default welcome intent, this comes through to Dialogflow
function welcome(agent) {
agent.add('This welcome message comes from Google Cloud Functions.');
}
// Default fallback intent, this also comes through
function fallback(agent) {
agent.add('This is the fallback response from Google Cloud Functions.');
}
function searchMyInfo(agent) {
// get parameters given by user in Dialogflow
const param1 = agent.parameters.param1;
const param2 = agent.parameters.param2;
const param3 = agent.parameters.param3
// this is logged
console.log('Parameters fetched from Dialogflow: ' + param1 + ', ' + param2 + ', ' + param3);
var myUrl = hostAPI + param1 + param2 + param3;
// the URL is correct and also logged
console.log('The URL is ' + myUrl);
// Everything up to here has happened between Dialogflow and Google Cloud Functions
// and inside GCF, and up to here it works
// Next, contact the host API to get the requested information via myUrl
// Using this as an example but *without* Firebase:
// https://github.com/dialogflow/fulfillment-weather-nodejs/blob/master/functions/index.js#L41
function getMyInfo(param1, param2, param3) {
console.log('Inside getMyInfo before Promise'); // this is logged
return new Promise((resolve, reject) => {
console.log('Inside getMyInfo after Promise'); // this is logged
console.log('Should get JSON from ' + myUrl);
rpn.get(myUrl, (res) => {
// The code is run at least up to here, since this is logged:
console.log('Inside rpn.get');
// But then the Google Cloud log just says
// "Ignoring exception from a finished function"
// and nothing below is logged (or run?)
let body = ''; // variable to store response chunks
res.on('data', (chunk) => {body += chunk;}); // store each response chunk
res.on('end', () => {
// this is not logged, so something must go wrong here
console.log('Inside res.on end block');
// Parse the JSON for desired data
var myArray = JSON.parse(body); // fetched JSON parsed into array
console.log(myArray); // not logged
// Here I have more parsing and filtering of the fetched JSON
// to obtain my desired data. This JS works fine for my host API and returns
// the correct data if I just run it in a separate html file,
// so I've left it out of this example because the problem seems
// to be with the Promise(?).
// Create the output from the parsed data
// to be passed on to the Dialogflow agent
let output = agent.add('Parsed data goes here');
console.log(output);
resolve(output); // resolve the promise
}); // res.on end block end
// In case of error
res.on('error', (error) => {
// this is not logged either
console.log('Error calling the host API');
reject();
}); // res.on error end
}); // rpn.get end
}); // Promise end
} // getMyInfo end
// call the host API: this does not seem to work since nothing is logged
// and no error message is returned
getMyInfo(param1, param2, param3).then((output) => {
console.log('getMyInfo call started');
// Return the results of the getMyInfo function to Dialogflow
res.json({'fulfillmentText': output});
}).catch(() => {
// no error message is given either
res.json({'fulfillmentText' : 'There was an error in getting the information'});
console.log('getMyInfo call failed');
});
} // searchMyInfo(agent) end
// Mapping functions to Dialogflow intents
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome); // this works
intentMap.set('Default Fallback Intent', fallback); // this works
intentMap.set('my.search', searchMyInfo); // this does not work
agent.handleRequest(intentMap);
}; // exports end
所以我的问题是:我怎样才能让这段代码工作以将履行响应返回给 Dialogflow?默认的欢迎和回退响应确实来自 Google Cloud Functions,但我的自定义意图 webhook 响应没有(即使在 Dialogflow 中为 my.search 设置了“启用 webhook 调用”)。