Search code examples
google-cloud-functionsdialogflow-cx

Error when deploying DialogFlow CX webhook on Google Cloud Functions: "Error: listen EADDRINUSE: address already in use :::8080"


I desperately try to implement a simple Webhook for my DialogFlow CX agent. Never done this before so I just copy paste the index.js and package.json code I found on the following page to my Google Cloud Function: DialogFlow CX calculate values

But it seems this is not working. When trying to deploy the Cloud Function I get the error "Error: listen EADDRINUSE: address already in use :::8080".

Same happens if I take this sample code: Dialogflow CX webhook for fulfilment to reply user using nodejs

What am I doing wrong? I am editing the code and trying to deploy it directly in the Google Cloude web console and not via a command prompt tool.

HERE SOME MORE DETAILS:

Setup of Google Cloud Function: I set up a new Google Cloud Function via Google Cloud Console by clicking Create Function. I set Region to us-east1, Trigger type to HTTP and Allow unauthenticated invocations. Then I save, update the index.js and package.json as described below and click Deploy. The result is that deployment could not be done because of Error: listen EADDRINUSE: address already in use :::8080.

Here the code I put into to index.js:

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

var port = process.env.PORT || 8080;

app.use(
    bodyParser.urlencoded({
      extended: true
    })
);
  
app.use(bodyParser.json());

app.post('/BMI', (req, res) => processWebhook4(req, res));

var processWebhook4 = function(request, response ){

    const params = request.body.sessionInfo.parameters;
    
    var heightnumber = params["height.number"];
    var weightnumber = params["weight.number"];
    var heightunit = params["height.unit-height"]
    var weightunit = params["weight.unit-weight"]
    var computedBMI;

    if (heightunit == "cm" && weightunit == "kg") { //using metric units
        computedBMI = ((weightnumber/heightnumber/heightnumber )) * 10000;
    } else if (heightunit == "in" && weightunit == "lb") { //using standard metrics
        computedBMI = ((weightnumber/heightnumber/heightnumber )) * 703;
    }

    const replyBMI = {
        'fulfillmentResponse': {
            'messages': [
                {
                    'text': {
                        'text': [
                            'This is a response from webhook! BMI is ' + computedBMI
                        ]
                    }
                }
            ]
        }
    }
    response.send(replyBMI);
}

app.listen(port, function() {
    console.log('Our app is running on http://localhost:' + port);
});

And here the code I put into package.json:

{
   "name": "cx-test-functions",
   "version": "0.0.1",
   "author": "Google Inc.",
   "main": "index.js",
   "engines": {
       "node": "8.9.4"
   },
   "scripts": {
       "start": "node index.js"
   },
   "dependencies": {
       "body-parser": "^1.18.2",
       "express": "^4.16.2"
   }
}

Solution

  • The code in the StackOverflow posts you’ve shared is working on other platforms such as Heroku.

    The error you encountered “Error: listen EADDRINUSE: address already in use :::8080” is because of the code function listening to port 8080. Note that you will need to check and edit the sample code you’ve provided, and see if the libraries used are supported (for example: express js) in Google Cloud Functions and if the libraries are compatible in order to use it in Google Cloud Functions.

    Here’s a working code for Cloud Functions from this StackOverflow Post:

    exports.helloWorld = (req, res) => {
     
      const params = req.body.sessionInfo.parameters;
      
       var heightnumber = params.height.number;
       var weightnumber = params.weight.number;
       var heightunit = params.height.heightUnit;
       var weightunit = params.weight.weightUnit;
       var computedBMI;
     
      if (heightunit == "cm" && weightunit == "kg") { //using metric units
          computedBMI = ((weightnumber/heightnumber/heightnumber )) * 10000;
       } else if (heightunit == "in" && weightunit == "lb") { //using standard metrics
           computedBMI = ((weightnumber/heightnumber/heightnumber )) * 703;
       }
     
       const replyBMI = {
           'fulfillmentResponse': {
               'messages': [
                   {
                       'text': {
                           'text': [
                               'This is a response from webhook! BMI is ' + computedBMI
                              
                           ]
                       }
                   }
               ]
           }
     }
     res.status(200).send(replyBMI);
    };
    

    Here’s the result:

    enter image description here

    Moreover, here’s a sample code you can also use for deploying in Cloud Function:

    index.js

    exports.helloWorld = (req, res) => {
     
     let fulfillmentResponse = {
              "fulfillmentResponse": {
                  "messages": [{
                      "text": {
                          "text": [
                              "This is a sample response"
                          ]
                      }
                  }]
              }
      };
      res.status(200).send(fulfillmentResponse);
    };
    

    package.json

    {
      "name": "sample-http",
      "version": "0.0.1"
    }
    

    Once you deployed the sample code, you can do the following to be able to use the webhook:

    1. Go to Manage > Webhooks > Create
    2. Add Display Name and Webhook URL(Trigger URL in Cloud Functions)
    3. Click Save
    4. Go to Build > Flow > Start Page
    5. Select any Route and add the webhook
    6. Test in Simulator

    Result should be like this:

    enter image description here