Выполнение NodeJs Dialogflow V2 - вызов метода webhook завершается до завершения обратного вызова - PullRequest
0 голосов
/ 06 июля 2018

Я разрабатываю веб-крючок Dialogflow, используя dialogflow-executement-nodejs клиента, чтобы найти температуру для города. При использовании служб для получения температуры для города все работает, и правильный ответ также генерируется, но ответ не отправляется пользователю, даже когда вызывается правильный метод.

Вот проблема в репозитории Dialogflow GitHub

Код

function getTemp(agent) {
    const timeStart = new Date().getTime();
    console.info(`temp function called`);
    // agent.add(`Temperature in New Delhi is 50 degree Celsius!`); // This works
    serviceRequest.getTemp("New Delhi", function(resp){
        if (resp['status'] === 'Y') {
            // success
            const msg = `Temperature in New Delhi is ${resp['temp']} Celsius!`;
            console.log(`Speech Response -- ${msg}`);
            console.log(`Type of msg -> ${typeof msg}`);
            agent.add(msg);
        } else {
            // failure
            agent.add(`There was some error with the backend. Please try again later.`);
        }
        const timeEnds = new Date().getTime();
        console.log("\nComplete 'getTemp' process took " + (timeEnds - timeStart) + " milliseconds.")
    });
    console.log("------ temperature function ends here ------");
}



'getTemp': function (city, callback) {
        let respBack = {};
        doTimeOutTest(function(resp){
            respBack['temp'] = resp;
            respBack['status'] = 'Y';
            callback(respBack);
        });

    }


function doTimeOutTest(callback){
    // below commented code takes < 10 ms to execute, but does not send any response back to dialogflow as call ends before it is executed
    // setTimeout(function() {
    //     callback("30 degree");
    // }, 1);

    // Below code works even when it takes more time to execute
    for(let i=0; i<10000; i++){
        for(let j=0; j<10000; j++){
            //
        }
    }
    callback("30 degree");
}

Журналы консоли

Когда запускается прокомментированный код

>>>>>>> S E R V E R   H I T <<<<<<<

temp function called
------ temperature function ends here ------
Speech Response -- Temperature in New Delhi is 30 degree Celsius!
Type of msg -> string

Complete 'getTemp' process took 10 milliseconds.


Когда код без комментариев запускается

>>>>>>> S E R V E R   H I T <<<<<<<

temp function called
Speech Response -- Temperature in New Delhi is 30 degree Celsius!
Type of msg -> string

Complete 'getTemp' process took 77 milliseconds.
------ temperature function ends here ------

Ссылка на код src NodeJS Dialogflow - https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Пример использования then-request :

const thenRequest = require('then-request');

function callApi(resolve){

    var req = thenRequest('POST', 'https://api_url_here...',{
      headers: 
       { 
        '.....': '....'
       }
    });

    req.done(function (res) {
        ....
        agent.add("Some text goes here...");
        ...
        resolve();
    });     
}

Запустить запрос:

return new Promise((resolve, reject) => { 
    callApi(resolve); 
});
0 голосов
/ 09 июля 2018

Вам нужно вернуть обещание в вашей функции обработчика. Обработчики функций теперь поддерживают обещания, поэтому вы можете возвращать обещание и обрабатывать в нем такие вещи, как http-запросы. Вот пример использования библиотеки запросов:

function dialogflowHanlderWithRequest(agent) {
  return new Promise((resolve, reject) => {
    request.get(options, (error, response, body) => {
      JSON.parse(body)
      // processing code
      agent.add(...)
      resolve();
    });
  });
};

Вы также можете переместить вызов HTTP в другую функцию, которая возвращает обещание. Вот пример с библиотекой axios:

function dialogflowHandlerWithAxios(agent) {
  return callApi('www.google.com').then(response => {
    agent.add('My response');
  }).catch (error => {
    // do something
  })
};

function callApi(url) {
    return axios.get(url);
}
...