dialogflow-es - 使用 agent.add() 发送动态数据作为响应
问题描述
我的要求是使用 Dialogflow 的 Nodejs 实现库测试版发送带有响应的动态数据。
我的查询是要知道发送动态数据和我们从外部 api 获得的响应的可能性?在某些情况下,我们需要通过调用 API 将实时数据发送到对话流代理(进而发送到客户端)。我尝试使用下面的代码来实现它,但它不起作用,这里的“值”是我们从 api 响应中获得的数据,并且已经解析/导航以提取 json 值。
agent.add(股票价格为 + JSON.parse(value).IRXML.StockQuotes.Stock_Quote[0].Trade)
在执行上述代码之前,我正在使用提升进行同步外部 API 调用,以便在 agent.add 部分中替换结果。
目前,我无法在promotion then 函数中执行agent.add 函数。请帮助我实现这一点,或者让我知道是否有任何替代方法可以做到这一点。
我进行了外部 api 调用以获取数据,以便我可以将相同的结果发送回代理。我可以打电话,但我真的不确定如何将收到的数据传递给代理。正如您在下面的代码中看到的那样,我正在调用 externalCall() 来进行 api 调用,这个函数是从 SpineDay() 调用的。从 externalCall() 返回的结果在 SpineDay() 中被替换,但结果仍然没有使用 agent.add() 传递给代理。“externalCall(req,res).then”中的任何指令 agent.add() 都不起作用。
function SpineDay(agent){
externalCall(req,res).then((output,agent) => {
//res.json({ 'fulfillmentText': JSON.parse(output).IRXML.StockQuotes.Stock_Quote[0].Trade });
agent.add(new Card({
title: output,
imageUrl: 'https://dialogflow.com/images/api_home_laptop.svg',
text: `This is the body text of a card. You can even use line\n breaks and emoji!`,
buttonText: 'Se rendre sur XXX',
buttonUrl: 'https://XXX/'
})
);
agent.add(new Suggestion(`Quelles sont les dernière sorties à la demande?`));
agent.add(new Suggestion(`Quel est le programme de ce soir?`));
}).catch(() => {
res.json({ 'fulfillmentText': `Error calling the weather API!` });
});
/*agent.add("Quelles sont les dernière sorties à la demande?");
agent.add("`Quel est le programme de ce soir?");*/
}
var externalCall = function(mainreq, mainres) {
return new Promise(function(resolve, reject){
// Create the path for the HTTP request to get the weather
var jsonObject = JSON.stringify(mainreq.body);
const agent = new WebhookClient({request: req, response: res});
console.log('In side post code' + Buffer.byteLength(jsonObject, 'utf8'))
// An object of options to indicate where to post to
var options = {
port: '443',
uri: 'https://xxxx.xxx.xxx//ticker/quote/stock?compid=22323&reqtype=quotes',
method: 'POST',
headers: {
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8'),
'X-MDT-API-KEY': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
}
};
// Make the HTTP request to get the weather
request(options, function(err, res, body) {
if (!err && res.statusCode == '200'){
// After all the data has been received parse the JSON for desired
// data
let response = JSON.parse(body).IRXML.StockQuotes.Stock_Quote[0].Trade;
// Create response
let output = "xxxx stock price is " +response;
// Resolve the promise with the output text
console.log(body);
resolve(output,agent);
}else{
console.log(`Error calling the weather API: ${error}`)
reject("Error calling the weather API");
}
});
});
}
解决方案
问题是您的SpineDay
函数正在进行 asyc 调用,但没有返回 Promise。虽然externalCall
是(正确地)使用 Promises,SpineDay
但不是。该库假定,如果您进行异步调用,您将返回一个 Promise,该 Promise 将在响应准备好发送时完成。
幸运的是,您可以在函数中添加几行来实现这一点,它们总体上返回一个 Promise,并返回一个 Promise 作为 Promise 链的一部分。
function SpineDay(agent){
return externalCall(req,res)
.then((output,agent) => {
agent.add(new Card({
title: output,
imageUrl: 'https://dialogflow.com/images/api_home_laptop.svg',
text: `This is the body text of a card. You can even use line\n breaks and emoji!`,
buttonText: 'Se rendre sur XXX',
buttonUrl: 'https://XXX/'
})
);
agent.add(new Suggestion(`Quelles sont les dernière sorties à la demande?`));
agent.add(new Suggestion(`Quel est le programme de ce soir?`));
return Promise.resolve();
}).catch(() => {
res.json({ 'fulfillmentText': `Error calling the weather API!` });
return Promise.resolve();
});
}
所以首先,你需要返回.then().catch()
链的结果,这将是一个 Promise。然后,在链内部,您还需要返回结果,这最好作为 Promise 完成。
推荐阅读
- mysql - MySql:如果我将 binlog 格式设置为 row,dose change buffer 仍然有效吗?
- fortran - 将数据存储在一维数组中
- jquery - “node_modules”文件夹的用途是什么?
- c++ - C++ 项目的 MakeFile
- python-3.x - 我怎样才能退回新的雪花?
- javascript - K6 负载测试 - 如何为整个测试运行创建顺序 ID
- angular - Angular 货币代码不适用于旧 Angular 版本
- python - python的正则化超几何函数1f2?
- angular - 在生产循环内时,角度 [隐藏] 不起作用
- graphql - 在 Apollo 客户端中突变后删除缓存