Machine learning chatbot with dialogflow, Jupyter notebook,flask,angular,nodeJS – part3

Last time, we used inline editor of dialogflow. But in this tutorial we make our own backend and will deploy it for doing the same thing that we did with the inline editor.

First Enable the Dialogflow API to generate a credential for dialogflow of your chatbot project(agent). Then download the credential file in json format for your project from here.
Make sure to you add this file in gitignore as it is a secret file which contains all your project credentials.
We will use dialogflow API where you will file all necessary instruction from here.

Assume you have node installed in your computer.
Now create your project folder where you will keep all your files. Also put the downloaded json file which contains all your credentials and rename it to credentails.json
Now run npm init to initialize a node application with package.json
Then install two necessary package
npm install dialogflow uuid
Now create a file named index.js
undefined
The content of the index.js file should be

const dialogflow = require('dialogflow');
const uuid = require('uuid');

const serviceAccount = require('./credentails.json');

/**
 * Send a query to the dialogflow agent, and return the query result.
 * @param {string} projectId The project to be used
 */
// replace your project ID here
async function runSample(projectId = 'titanic-agent-11111') {
  // A unique identifier for the given session
  const sessionId = uuid.v4();

  // Create a new session
  const sessionClient = new dialogflow.SessionsClient({ credentials: serviceAccount  });
  const sessionPath = sessionClient.sessionPath(projectId, sessionId);

  // The text query request.
  const request = {
    session: sessionPath,
    queryInput: {
      text: {
        // The query to send to the dialogflow agent
        text: 'hello',
        // The language used by the client (en-US)
        languageCode: 'en-US',
      },
    },
  };

  // Send request and log result
  const responses = await sessionClient.detectIntent(request);
  
  console.log('Detected intent');
  const result = responses[0].queryResult;
  
  console.log(`  Query: ${result.queryText}`);
  console.log(`  Response: ${result.fulfillmentText}`);
  
  if (result.intent) {
    console.log(`  Intent: ${result.intent.displayName}`);
  } else {
    console.log(`  No intent matched.`);
  }
}

runSample()

Dont forget to find the project ID and replace it in the code.
Now run node index.js and you will see the response.
When we typed hi in the dialogflow we got a response from the bot.
Here with our custom backend we got the same.
If you got below response (or your desired response) then so far everything is working fine.

undefined

Now we have to extend this and we will also attach the webhook here.
Install some npm packages to fulfill our requirements

// install fulfillment and actions to integrate fulfillment in our backend
npm i dialogflow-fulfillment actions-on-google
// install axios to make http request
npm i axios
// install cors for enabling cross origin 
npm i cors
// install express and parser for node server and parse the body from the http request
npm i express body-parser

We will make two request method namely getBotResponse and dialogflowWebhook, one for handling request- response from dialogflow and another for handling webhook when intent is executed. We will listen the server at 3000 port.

skeleton of index.js
undefined

Our final code for index.js is given below:

const dialogflow = require('dialogflow');
const uuid = require('uuid');
const cors = require('cors');
const serviceAccount = require('./credentails.json');
const { WebhookClient } = require('dialogflow-fulfillment');
const axios = require('axios');
const express = require('express')
const bodyParser = require('body-parser');
const app = express()
const port = 3000
/**
 * Send a query to the dialogflow agent, and return the query result.
 * @param {string} projectId The project to be used
 */
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

app.use(cors())

app.get('/', (req, res) => res.send('Hello World!'))

app.get('/test', (req, res) =>{
	 res.json({msg: 'This is CORS-enabled for all origins!'})
})


app.post('/getBotResponse', async (request, response) =>{
	console.log(request.body)
    const { queryInput,sessionId  } = request.body;
	//const sessionId = uuid.v4();

    const sessionClient = new dialogflow.SessionsClient({ credentials: serviceAccount  });
    const session = sessionClient.sessionPath('titanic-agent-1-puqxqx', sessionId);
    console.log(sessionId)
    const responses = await sessionClient.detectIntent({ session, queryInput});

    const result = responses[0].queryResult;
	
	response.json(result)

})



app.post('/dialogflowWebhook',async (request, response) => {
   const agent = new WebhookClient({ request, response });

    console.log(JSON.stringify(request.body));

    const result = request.body.queryResult;
	console.log(request.body.queryResult)
   
    function welcome(agent) {
      agent.add(`Welcome to my agent!`);
    }
   
    function fallback(agent) {
      agent.add(`Sorry, can you try again?`);
    }
	
	let intentMap = new Map();
    intentMap.set('Default Welcome Intent', welcome);
    intentMap.set('Default Fallback Intent', fallback);
    intentMap.set('titanic.inputs', getPrediction);
    agent.handleRequest(intentMap);
	
	function getPrediction(agent) { 
    const name = agent.parameters.name,
          age = agent.parameters.age,
          gender = agent.parameters.gender,
          family_size = agent.parameters.family_size,
          ticket_class = agent.parameters.ticket_class,
          ticket_price = agent.parameters.ticket_price,
          embark = agent.parameters.embark;

   console.log(name,age,gender,family_size,ticket_class,ticket_price,embark)
    var title,ag,sex,fare,pclass,fsize,mbark;
    
    if(name.toLowerCase().includes("Mr")) title=0;
    else  if(name.toLowerCase().includes("Mrs")) title=1;
    else  if(name.toLowerCase().includes("Miss")) title=2;
    else  if(name.toLowerCase().includes("Master")) title=3;
    else title=4;
    
    
    if(age<=14) ag=0;
    else if(age>14 && age<=22) ag=1;
    else if(age>22 && age<=36) ag=2;
    else if(age>36 && age<=55) ag=3;
    else ag=4;
    
    sex= gender === 'male'?0:1;
    
    if(ticket_price.toLowerCase().startsWith("l")) fare=0;
    else if(ticket_price.toLowerCase().startsWith("m")) fare=1;
    else if(ticket_price.toLowerCase().startsWith("h")) fare=2;
    else fare=3;
    
    if(ticket_class==='1') pclass=1;
    else if(ticket_price==='2') pclass=2;
    else  pclass=3;
    
    if(family_size===1) fsize=0;
    else if(family_size<=3) fsize=1;
    else fsize=2;
    
    if(embark.toLowerCase().startsWith("s")) mbark=0;
    else if(embark.toLowerCase().startsWith("q")) mbark=1;
    else  mbark=1;
    
    console.log(`data ........`+title+` `+ag+` `+sex+` `+fare+` `+pclass+` `+fsize+` `+mbark);
        return axios.post('https://titanic-project-backend.herokuapp.com/predict',{"data":[title,ag,sex,fare,pclass,fsize,mbark]})
		//return axios.post('https://titanic-project-backend.herokuapp.com/predict',{"data":[0,1,1,0,1,0,0]})
        .then(function (response) {
           console.log(`I ........response`);
           console.log(response.data);
           console.log(`response `,response.data);
          if(response.data==1) 
          {
            agent.add(`According to the ML model, it seems you would survive if you were at titanic on that time.`);
          }
          else agent.add(`According to the ML model, it seems you wouldn't survive if you were at titanic on that time.`);

        })
        .catch(function (error) {
          console.log(error);
           agent.add(`I'm sorry,something went wrong`);
        });
  }

   
});


app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`)) 

Run the node server by node index.js and it will serve at http://localhost:3000

In the next part, we will use these two methods in our custom chat UI.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s