我一直在研究DialogFlow很长一段时间。我在这里遇到了一个问题。另请注意,我是Node JS的新手。
我有一个函数来进行HTTP调用,因为我需要频繁地调用我的intent函数。使用Callback函数我得到了从被调用函数返回到调用函数的结果。一切都很好,直到这里。下一步,我想使用“WebhookClient.add()”将返回的响应发送给用户。
但问题是,它没有向用户发送响应。但是当我试图在日志中打印返回的值时,它工作正常。 我甚至尝试将返回的变量复制到全局变量中并使用WebhookClient.add()将其发送回用户,但它将用户作为UNDEFINED响应为全局变量的值。
以下是我的代码:
var doco;
//My intent function
function createSalesOrder(agent) {
const soldTo = agent.parameters.soldTo;
const shipTo = agent.parameters.shipTo;
const customerPO = agent.parameters.custPO;
const mcu = agent.parameters.mcu;
const item = agent.parameters.item;
const qty = agent.parameters.qty1;
var doco1;
orchName = 'JDE_ORCH_SALESORDER_GA';
postData1 = {
"inputs": [{
"name": "Customer PO",
"value": customerPO
}, {
"name": "Sold To",
"value": soldTo
}, {
"name": "Ship To",
"value": shipTo
}, {
"name": "BusinessUnit",
"value": mcu
}, {
"name": "Item Number",
"value": item
}, {
"name": "Quantity Ordered",
"value": qty
}]
};
postData = JSON.stringify(postData1);
//Calling the external function for network call
networkCall(postData,orchName,function(response){
doco1 = response.ServiceRequest1.fs_P42101_W42101D.subforms.s_W42101D_S421007A_181.data.z_DOCO_137.value;
console.log("DOCO "+doco1);
doco = doco1;
agent.add(`Document number is ${doco1}`);//Here the response is sent to dialogflow i.e google assistant is not reading this response to the user
});
agent.add(`Document number is ${doco}`);//Here the value is read back to the user as UNDEFINED.But it has the value in a global variable
}
以下是我所谓的功能:
function networkCall(postData, orchName,callback) {
const options = {
hostname: '<hostname>',
port: <port>,
path: '<path>' + orchName,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
},
auth: 'user:pwd'
};
console.log("options:" + options);
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
data = JSON.parse(chunk);
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
callback(data);
console.log('==END RESPONSE==');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
}
我想再次重复一遍,在调用函数中,这里输出的是“doco1”,但是没有调用agent.add()。除了那部分外,一切正常。
请指导我如何将价值发回给用户。
感谢。
更新: 我已将代码更改为:
//function call
return httpRequest(postData1)
.then((message)=> {
agent.add(`SUCCESS`);
return Promise.resolve()
})
.catch((err) => {
console.log(err);
agent.add("Uh oh, something happened.");
return Promise.resolve();
})
//called function
var options = {
method: 'post',
uri: 'url',
body: myJSONObject,
auth: {
'user': 'usr',
'pass': 'pwd'
},
json: true
};
return rp( options )
.then( body => {
var doco =body.ServiceRequest1.fs_P42101_W42101D.subforms.s_W42101D_S421007A_181.data.z_DOCO_137.value;
console.log('DOCO '+doco);
return Promise.resolve( doco );
})
.catch( err => {
console.log('FAILED'+err);
// You should also return a message here of some sort
return Promise.resolve( err );
});
TypeError: Cannot read property 'prototype' of undefined
at module.exports (/user_code/node_modules/request-promise-native/node_modules/request-promise-core/configure/request2.js:34:47)
at Object.<anonymous> (/user_code/node_modules/request-promise-native/lib/rp.js:15:1)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3)
at Module.require (module.js:504:17)
at require (internal/module.js:20:19)
at networkCall (/user_code/index.js:174:16)
Function execution took 663 ms, finished with status: 'crash'
问题在于package'request-promise-native'。请帮我如何导入它并为其添加依赖。我已将依赖添加为“request-promise-native”:“*”
答案 0 :(得分:0)
问题是networkCall()
是一个异步执行其工作的函数,但Dialogflow库假定如果您正在执行异步操作,则处理程序将返回Promise。由于您没有返回Promise,因此只要函数返回,响应就会发送给用户。由于您的异步调用尚未完成,因此会在没有信息的情况下发送。
你有一些问题的解决方案,但它们都涉及返回某种Promise,所以阅读Promises会有所帮助。
我建议修改networkCall()
以返回承诺。执行此操作的最佳方法是使用request-promise-native
包替换http.request()
。我没有测试过,但它可能看起来像这样:
function networkCall(postData, orchName,callback) {
const options = {
hostname: '<hostname>',
port: <port>,
path: '<path>' + orchName,
method: 'POST',
body: postData,
json: true,
auth: 'user:pwd'
};
console.log("options:" + options);
const rp = require('request-promise-native');
return rp( options )
catch( err => {
console.err('Something went wrong in the call.',err);
Promise.reject( err );
});
};
然后您在createSalesOrder()
中对它的调用就像是
// Note I use postData1, since it takes the JSON object
return networkCall(postData1,orchName)
.then( response => {
var doco1 = response.ServiceRequest1.etc.etc.etc.value;
console.log('DOCO '+doco1);
return agent.add(`Document number is ${doco1}`);
})
.catch( err => {
return agent.add('Something went wrong.);
});