0

我已经在 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”:“*”

4

1 回答 1

0

问题是这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.);
  });
于 2018-06-17T18:58:45.867 回答