Невозможно отправить ответ в диалог
Я уже давно работаю над DialogFlow. У меня возникла проблема. Также обратите внимание, что я новичок в Node JS.
У меня была функция для выполнения HTTP-вызовов, так как мне часто нужно было выполнять эти вызовы по отношению к моим целевым функциям. Используя функции обратного вызова, я получил полученный результат обратно от вызываемой функции к вызывающей функции. Все хорошо, пока здесь. Далее, я хочу отправить ответный ответ пользователю, используя "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'
проблема в пакете 'quest-обещание-родной'. Пожалуйста, помогите мне, как импортировать его и добавить зависимость к нему. Я добавил зависимость как "запрос-обещание-нативный":"*"
1 ответ
Проблема в том, что networkCall()
это функция, которая выполняет свою работу асинхронно, но библиотека Dialogflow предполагает, что если вы выполняете асинхронные операции, ваш обработчик вернет Promise. Поскольку вы не возвращаете обещание, как только ваша функция возвращается, ответ отправляется пользователю. Поскольку ваш асинхронный вызов еще не завершен, он отправляется без информации.
У вас есть несколько решений вашей проблемы, но все они связаны с возвратом какого-либо Обещания, так что ознакомление с Обещаниями поможет.
Что я хотел бы предложить, чтобы изменить networkCall()
вернуть обещание. Лучший способ сделать это - заменить http.request()
с request-promise-native
пакет. Я не проверял, но это может выглядеть примерно так:
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.);
});