3

I would like to connect a custom chatbot in Dialogflow with a PostgreSQL database. The scenario is that the user submits his/her queries to the bot and in turn it commits SQL queries to the database. I know that Webhook/Fulfillment and Integration should be used but the question is how.

Until now, I tried to code in Fulfillment/Inside Editor by by putting...

const pg = require('pg');
const connectionString = process.env.DATABASE_URL || 'postgres://un:pass@localhost:5432/postgres';
const client = new pg.Client(connectionString);
client.connect();
const query = client.query('CREATE TABLE items(id SERIAL PRIMARY KEY, text VARCHAR(40) not null, complete BOOLEAN)');
    query.on('end', () => { client.end(); });

...into index.js. Also, when trying over Google Assistant I always get a Webhook error without any indicative explanation:

textPayload: "MalformedResponse: Webhook error (206)"  

I don't want to connect the bot to an additional intermediate website; the chatbot should be able to do the queries and check the database by itself.

Does somebody have an advice for me? Thank you!

An excerpt of the Log is given below:

7:10:03.013 PM
dialogflowFirebaseFulfillment
Ignoring exception from a finished function
7:10:02.995 PM
dialogflowFirebaseFulfillment
Function execution took 10 ms, finished with status code: 200
7:10:02.986 PM
dialogflowFirebaseFulfillment
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
7:10:02.986 PM
dialogflowFirebaseFulfillment
Function execution started
7:09:49.540 PM
dialogflowFirebaseFulfillment
Ignoring exception from a finished function
7:09:48.543 PM
dialogflowFirebaseFulfillment
Function execution took 865 ms, finished with status code: 200
7:09:47.678 PM
dialogflowFirebaseFulfillment
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
7:09:47.678 PM
dialogflowFirebaseFulfillment
Function execution started
7:09:12.659 PM
dialogflowFirebaseFulfillment
Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail
7:08:41.442 PM
dialogflowFirebaseFulfillment
Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail
7:04:51.279 PM
dialogflowFirebaseFulfillment
Ignoring exception from a finished function
7:04:51.238 PM
dialogflowFirebaseFulfillment
Function execution took 896 ms, finished with status code: 200
7:04:50.343 PM
dialogflowFirebaseFulfillment
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
7:04:50.343 PM
dialogflowFirebaseFulfillment
Function execution started
7:04:33.195 PM
dialogflowFirebaseFulfillment
Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail
Sairaj Sawant
  • 1,842
  • 1
  • 12
  • 16

1 Answers1

4

I recently wrote about connecting MongoDB with Dialogflow here.

As I have stated before you won't be able to connect to a local instance of your Postgres running on localhost:5432 (neither MySQL on localhost:8080). You have to use a hosted Postgres service like ElephantSQL (for other databases as well except Firebase/Firestore.)

Now to moving toward your answer, First of all, it is important to take this log message seriously:

Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions

To address this it is extremely important you use a Billing Account, for example, a Blaze Plan of firebase to access external networks (that are databases hosted as a service in your case) Refer this.

Code

'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');

const pg = require('pg');
const connectionString = process.env.DATABASE_URL || 'postgres://fsdgubow:K4R2HEcfFeYHPY1iLYvwums3oWezZFJy@stampy.db.elephantsql.com:5432/fsdgubow';
const client = new pg.Client(connectionString);
client.connect();
//const query = client.query('CREATE TABLE items(id SERIAL PRIMARY KEY, text VARCHAR(40) not null, complete BOOLEAN)');

});

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  function welcome(agent) {

     const text = 'INSERT INTO items(text, complete) VALUES($1, $2) RETURNING *'
     const values = ['some item text', '1' ]

    // insert demo in your items database
    client.query(text, values)
      .then(res => {
        console.log(res.rows[0])
        //see log for output
      })
     .catch(e => console.error(e.stack))

    // sample query returning current time...
     return client.query('SELECT NOW() as now')
           .then((res) => { 
               console.log(res.rows[0]);
               agent.add(`Welcome to my agent! Time is  ${res.rows[0].now}!`);
           })
           .catch(e => console.error(e.stack))

  }

  function fallback(agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
}

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('welcome', welcome);
  intentMap.set('Default Fallback Intent', fallback);
  // intentMap.set('your intent name here', yourFunctionHandler);
  // intentMap.set('your intent name here', googleAssistantHandler);
  agent.handleRequest(intentMap);

});

ElephantSQL Console

console

Firebase Logs

logs

Google Assistant

assistant

I have used ElephantSQL for demo here. Look for more queries. Make sure you place return before them to execute successfully and avoid "MalformedResponse: Webhook error (206)"!

Hope that answers all your queries. Good Luck!

Sairaj Sawant
  • 1,842
  • 1
  • 12
  • 16