1
votes

I am developing a Dialogflow webhook using dialogflow-fulfillment-nodejs client to find temperature for a city. While using the services to fetch the temperature for a city, everything works and the correct response is also generated but the response is not sent to the user even when the right method is called.

Here is the issue in the Dialogflow GitHub repo

Code

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");
}

Console Logs

When the commented code runs

>>>>>>> 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.


When the uncommented code runs

>>>>>>> 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 ------

NodeJS Dialogflow src code link - https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js

2
The problem likely lies in the code you’ve omitted from this question. - Robert Levy
I have added the complete code for the function and log trace - Abhinav Tyagi
Interesting... if you look at the code for the dialogflow fulfillment package you can see where they use instanceOf but it’s got the right side as things it defines or imports rather that user parameters. My best guess would be to nuke your node_modules directory and do a fresh npm install - Robert Levy
Deleted the Node Module of the project and reinstall using sudo npm install. Still the same error :( - Abhinav Tyagi
Their documentation says to use version ^1.0.0 but no version found above ^0.4.1 which I am using !! - Abhinav Tyagi

2 Answers

3
votes

You need to return a promise in your handler function. function handlers support promises now so you can return a promise and process things like http requests in the promise. Here is an example of using the request library:

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

You can also move the HTTP call to another function that returns a promise. Here is an example with the axios library:

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);
}
0
votes

An example using 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();
    });     
}

Fire the request:

return new Promise((resolve, reject) => { 
    callApi(resolve); 
});