【问题标题】:Unable to send response to dialogflow无法向对话流发送响应
【发布时间】:2018-11-26 15:35:39
【问题描述】:

我从事 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' 

问题在于包'request-promise-native'。请帮助我如何导入它并为其添加依赖项。我已将依赖项添加为“request-promise-native”:“*”

【问题讨论】:

    标签: node.js dialogflow-es google-assistant-sdk google-assist-api


    【解决方案1】:

    问题在于networkCall() 是一个异步执行其工作的函数,但 Dialogflow 库假定如果您正在执行异步操作,您的处理程序将返回一个 Promise。由于您不返回 Promise,因此一旦您的函数返回,响应就会发送给用户。由于您的异步调用尚未完成,它会在没有信息的情况下发送。

    您有一些解决问题的方法,但它们都涉及返回某种 Promise,因此阅读 Promise 会有所帮助。

    我建议修改networkCall() 以返回一个Promise。最好的方法是将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.);
      });
    

    【讨论】:

    • 感谢您的回复。我试过了,但应用程序崩溃了。 TypeError:无法在 Object. 处读取 module.exports (/user_code/node_modules/request-promise-native/node_modules/request-promise-core/configure/request2.js:34:47) 处未定义的属性“原型” (/user_code/node_modules/request-promise-native/lib/rp.js:15:1) 在 Module._compile (module.js:577:32) 在 Object.Module._extensions..js (module.js:586 :10) 在 Module.load (module.js:494:32) 在 tryModuleLoad (module.js:453:12) 在 Function.Module._load (module.js:445:3)
    • (续) 在 Module.require (module.js:504:17) 在 require (internal/module.js:20:19) 在 networkCall (/user_code/index.js:174: 16) 函数执行耗时 663 毫秒,完成状态为:'crash'
    • 检查参数,因为我不确定我是否都正确。如果您仍然遇到问题,请更新您的原始问题以显示您在做什么,而不是尝试在 cmets 中提供代码或错误消息。
    • 还要检查您使用的 node.js 版本以及它是否支持原生承诺。
    • 你能告诉我如何检查这些东西吗?这听起来可能很幼稚,但请帮帮我
    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2013-09-14
    • 2014-07-19
    相关资源
    最近更新 更多