无法向对话框

时间:2018-06-17 16:24:52

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

我一直在研究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”:“*”

1 个答案:

答案 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.);
  });