Newsletter robot
Enjoying the read?

Don't miss our next article

Even though most chatbot projects are customer-facing, it is estimated that up to 26% of chatbots are operations focused. Google's Dialogflow is a popular platform for building and deploying chatbots as it's easy to setup a conversational interface with – and free to use.

In this guide, we'll create a Dialogflow chatbot for a work-related, internal use case. Specifically, we will focus on the data-binding aspect to see just how compatible Dialogflow is with integrating enterprise data.

1. Create an agent

Creating a new agent in Dialogflow

Dialogflow is free to get started with; all you need is to do is register for an account. Then click on Create Agent and assign a name, language and Google Project to the agent.

In this example we simply named our agent Workbot.

2. Create an intent

In our new Workbot agent we first will create an intent. An intent is basically what project managers refer to as a 'user story'.

For example, 'looking up your leave allowance' or 'book a training session' would be an intent the chatbot should assist the employee with. As an example for this guide, we will be making a chatbot that looks up statistics about your website's visitors.

We chose this an example as it consumes another Google API which is free to do with Dialogflow's Firebase Cloud Functions. Note that Firebase Cloud Functions has a free tier with significant limitations, so make sure to consider the cost of running functions which connect to external APIs.

Related article:
Want to build a chatbot for your team or organization but not sure what would work best for you? We have a full-length guide covering the start to finish process of scoping, building and deploying a chatbot for your workplace.

3. AI training data

The Natural Language Understanding in Dialogflow can differentiate between different intents that a user may have, we need to start entering some training phrases.

Ask yourself all of the different ways you can think of to ask for your intent and enter those to start, for example:

  • How many visitors did we have in the last 30 days?
  • Website visitors past 30 days
  • How many people visited our website in the past month?
  • Show me how many people visited our page in the last 14 days
  • ...

Try and create a wide spread of phrases. By including questions and commands, using active and passive voice where possible and including synonyms for our key trigger words (i.e. visitors, users or people should have the same meaning to the bot) you will give your chatbot a better chance of understanding and responding to your users.

Putting some thought into this early training data should help the AI get it right more often. However, it won't completely get you around having to occasionally retrain the AI using Analytics data.

You may notice the little yellow highlights around the time values, i.e. past 30 days. These represent parameters that the chatbot can capture dynamically from the user. There can be multiple such parameters which each get their own color, e.g. if you enter country names it could be orange.

Example of Dialogflow recognizing an entity in a user query

For the most part this detection should happen by itself as you feed the bot more training sentences. But if you go to the Action and parameters section you can manage what parameters you will have.

Dialogflow actions and parameters options

We'll only use the time period parameter in this example, as you will later see that every additional parameter creates a lot of extra code.

4. General configuration

Next up are two small matters to deal with: Responses and Fulfilment.

As a response we only really need a fallback answer the bot will resort to, in case it couldn't find an answer for the question.

Why only a fallback? Unlike the training questions, that have those handy highlighted bits to show parameters, there isn't an elegant way to just write text answers and mark spots as placeholders for the number.

Instead we will have to build our answer as part of the Fulfilment script we're going to write below.

Adding a fallback text response to a Dialogflow chatbot

That means all we need to write is "I'm sorry, something went wrong" and continue with the Fulfilment section below.

Turning on webhooks for a Dialogflow intent

Fulfilment is basically what we tell the bot to do or execute, once Dialogflow determined the correct intent.

For our example we just need to enable the toggle for Enable webhook call for this intent.

5. Start with fulfillment

Image from u/ThePeoplesBard

Fulfilment is where our bot learns to actually give the user a direct answer; as opposed to relying on canned responses or randomly sputtering out links to go somewhere else.

Without fulfilment the bot will have a very hard time to get long-term user adoption as it simply isn't that useful. Instead, by reaching out to external APIs, your chatbot can respond dynamic information from an application - meaning your users can get more from your chatbot than a simple scripted knowledge base.

To start, we click on the Fulfilment menu on the left, and then we enable the Inline Editor.

Writing a Dialogflow webhook handler using Firebase Cloud Functions

Now comes the arguably hardest part and that is writing our fulfillment function.

6. Write fulfilment function

Our function is going to be a webhook function, meaning it is a function that gets triggered by a HTTP request – and Dialogflow will be making this request if it matched the user's query to an existing intent.

Webhooks can be stored on many services like AWS Lambda, Heroku or Azure. But Google conveniently offers it's own service with Cloud Functions for Firebase which we are going to use for our example.

Editor's tip:
Writing fulfilment functions can be technically challenging! We've included our function for the Google Analytics API below, but your function will depend heavily on the API you're getting information from. (If you don't want to go through the hassle of writing functions, you can get a Digital Assistant for free - it includes connectors to over 50 applications out of the box, with zero code needed.)

Our webhook needs to do four things:

  1. Parse the agent parameters

  2. Connect to our data source (in this case Google Analytics)

  3. Request the data

  4. Return it to Dialogflow in a readable format (i.e. a Card or some text)

To begin with, we'll focus on the package.json file which contains a list of dependencies (necessary resources) for our function. Let's add the googleapis package which shall allow us to easily communicate with the Google Analytics API.

Updating the package.json for a Dialogflow Firebase webhook function

At the time of writing the latest version was 27, so we're adding to line 20 this:

"googleapis": "^27.0.0"

(Don't forget to add a comma on line 20 at the end.)

Now we go over to index.js where our main function belongs.

We've got the finished code for this further down, so skip ahead if you want but just in case I'll walk you through each section.

'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis'); // Calling the googleapis dependency we added earlier
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');

These are our project dependencies, where we simply add a new line for googleapis so we can call it in the function.

// Set up view ID from Google Analytics
const viewid = 'Your_view_Id';
// Google Analytics API service account details
const serviceAccount = {};

The view ID is the view in Google Analytics that you want to pull information from. You can find this in the Google Analytics admin panel. ServiceAccount is an account Google APIs uses to authenticate with the Google Analytics API service. You'll need to register for a service account.

There's a good guide here, but here's a quick overview:

  1. Go to the Google Developer Console APIs page and create a new project

  2. From the dashboard, click Enable APIs and services

  3. Search for the Google Analytics API and open it. Click Enable to enable it

  4. When prompted, click Create Credentials and then Help me choose

  5. Fill out the form as follows:

  6. Fill in the form to create a service account, with a JSON key type

  7. The form will download a JSON file containing the details of your service account to your PC.

  8. Once you've got this JSON file, you can copy and paste the contents of the file in place of the empty curly brackets.

    You'll also need to add your service account to your Google Analytics account as a user. You can do this in the Google Analytics admin panel under User Management. When prompted, add the email address listed under client_email.

    const serviceAccountAuth = new google.auth.JWT({
    email: serviceAccount.client_email,
    key: serviceAccount.private_key,
    scopes: 'https://www.googleapis.com/auth/analytics.readonly'
    });

We now authenticate with the Google API service for Google Analytics. The 'scopes' variable refers to what level of access your function requires. You should always choose the lowest level that you need; you can read more about scopes on the Google Identity Platform documentation.

const startDate = agent.parameters['date-period'].startDate.split('T')[0];
const startDateString = getLocaleDateString(startDate);
const endDate = agent.parameters['date-period'].endDate.split('T')[0];
const endDateString = getLocaleDateString(endDate);

The first thing our agent needs to do is parse the user-provided parameters into a usable format. Google Analytics requires a specific date format for its API, but we also want to create a user-readable date string that our agent can respond to the user with.

Preview available intent parameters in the test sidebar of Dialogflow when triggering an intent

Parameters provided by the agent are accessible under agent.parameters; you can see all available parameters from a response in the test window:

getLocaleDateString(date) is just a helper function which parses the dates.

function getVisitorCount(agent) {
return getPageviews(startDate, endDate).then((visitorString) => {
agent.add(`In the period ${startDateString} to ${endDateString}, there were ${visitorString} visitors to yourwebsite.com.`);
}).catch(() => {
agent.add(`Sorry, we couldn't retrieve data for the period ${startDateString} to ${endDateString}. Is there anything else I can do for you?`);
});
}

This is our actual intent handler. If the agent matches a request to an intent, this is the function that gets called. The function calls our API caller function getPageviews(), then depending on whether the function was successful or failed, sends a response back to the agent.

So if something was found we've got the sentence In the period between [startDate] to [endDate], there were [number] visitors to yourwebsite.com.

And if we can't get a valid result we will return to Dialogflow simply Sorry, we couldn't retrieve data for the period [startDate] to [endDate]. Is there anything else I can do for you?

Notice how the negative response is different to our fallback response from point 4. The fallback response only gets used if our function doesn't respond for whatever reason.

let intentMap = new Map();
intentMap.set('Page visitor count', getVisitorCount);
agent.handleRequest(intentMap);

The intent map maps each intent defined on the intent tab to a function. When our 'Page visitor count' intent is invoked, it will call our function getVisitorCount(). You can map more intents to functions here to add more functionality to your chatbot.

Dialogflow uses just one webhook to handle all intents for the same agent. So depending on how many different use cases this chatbot should handle, there might be quite a few more functions that you will want to squeeze in here. 😉

7. Interacting with the API

Following on from this we now start to actually use the Google Analytics API.

// Analytics API caller
function getPageviews(startDate, endDate) {
return new Promise((resolve, reject) => {
// Make request to Google Analytics - start and end date provided by user
google.analytics('v3').data.ga.get({
'auth': serviceAccountAuth,
'ids': 'ga:' + viewid,
'start-date': startDate,
'end-date': endDate,
'metrics': 'ga:pageviews'
}, (err, resp) => {
if (err) {
// Something went wrong
console.log(err);
reject (err);
} else {
// Data received from GA
var count = resp.data.rows[0][0];
resolve(count);
}
});
});
}

We use promises to ensure that our function gets the data it needs before it proceeds. We then make the request to the Google Analytics API using the analytics('v3').data.ga.get method. The parameters it takes are well documented here, but you can query almost any aspect of your Analytics data with the API.

Here is our function again as one:

'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
// Set up view ID from Google Analytics
const viewid = '12345678';
// Google Analytics API service account details
const serviceAccount = {
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "..."
...
};
// Authenticate with Google API services
const serviceAccountAuth = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: 'https://www.googleapis.com/auth/analytics.readonly'
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
// Parse the user provided date parameters into Date object and human readable formats
const startDate = agent.parameters['date-period'].startDate.split('T')[0];
const startDateString = getLocaleDateString(startDate);
const endDate = agent.parameters['date-period'].endDate.split('T')[0];
const endDateString = getLocaleDateString(endDate);
// Intent handler - creates user responses for success or failure
function getVisitorCount(agent) {
return getPageviews(startDate, endDate).then((visitorString) => {
agent.add(`In the period ${startDateString} to ${endDateString}, there were ${visitorString} visitors to adenin.com.`);
}).catch(() => {
agent.add(`Sorry, we couldn't retrieve data for the period ${startDateString} to ${endDateString}. Is there anything else I can do for you?`);
});
}
let intentMap = new Map();
intentMap.set('Page visitor count', getVisitorCount);
agent.handleRequest(intentMap);
});
// Analytics API caller
function getPageviews(startDate, endDate) {
return new Promise((resolve, reject) => {
// Make request to Google Analytics - start and end date provided by user
google.analytics('v3').data.ga.get({
'auth': serviceAccountAuth,
'ids': 'ga:' + viewid,
'start-date': startDate,
'end-date': endDate,
'metrics': 'ga:pageviews'
}, (err, resp) => {
if (err) {
// Something went wrong
console.log(err);
reject (err);
} else {
// Data received from GA
var count = resp.data.rows[0][0];
resolve(count);
}
});
});
}
// Helper function to convert date into a user-readable string
function getLocaleDateString(date) {
let dateObj = new Date(date);
return dateObj.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', timeZone: 'America/Los_Angeles' });
}

Once the API has responded, we pull out the information we need and pass this back to our intent fulfilment function. The response format is detailed here, but you might find it easier to just print the response to the console to figure out what you need.

8. Debugging

Okay that was a lot already, but like any good developer you'll want to test this code extensively now.

There is debugging available through the Firebase console. There's a link to this underneath the function editor.

Link to view execution logs in Firebase for debugging Dialogflow webhook functions

You can use console.log() to print to the Firebase console, and other debugging and error messages are viewable here. General messages about the webhook status can also be seen under Diagnostic Info when you test your chatbot in the Dialogflow console.

Diagnostic info from the Dialogflow API in the Firebase console

9. Deploy the function

We can't yet deploy our chatbot to our users, but we can deploy our function now. To do that, just click Deploy.

Dialogflow will notify you once the deployment is complete, and you'll also see a message in the Firebase console. If there are any errors with the deployment, these will be logged in Firebase too.

You can now use the Dialogflow console on the right to test your chatbot. Start with one of your training phrases to see if the chatbot is communicating with the API properly.

If so, you can start to test more user phrases to find blind spots in your training phrase list. Your chatbot will work by default with Google Assistant, but of course you can deploy it to many more services.

10. Deploy the chatbot

We've worked hard to get this chatbot up and running, and thankfully the one thing Dialogflow make easier than anything else is deploying your chatbot to other channels.

Let's say you want to deploy your chatbot to Slack (as it is an employee-facing example), then just open the Integrations page, enable the toggle for Slack and authorize Dialogflow with your Slack workspace.

In Slack simply add the Dialogflow Bot to your Apps and start asking away.

Editor's tip:
Dialogflow is missing some important enterprise deployment options, and the existing deployment channels can require quite a bit of set-up to be user-ready for your organization. If you want to use your chatbot with other enterprise apps like Microsoft Teams, or embed it in your intranet, you'll need to put in some extra legwork (or you could consider using a free tool like Digital Assistant if you'd rather make life easy for yourself).

Bottom line

As you can see, creating even a rather simple chatbot with Dialogflow requires a deep understanding of Webhooks and APIs. If you're building a chatbot for your workplace, you'd likely need to enlist the help of a developer to assist with building functions and deploying your chatbot to the channels your employees work in.

Plus icon Easy to train the AI
Plus icon Easy to mark parameters
Plus icon Deployment to multiple chat channels is super quick

Minus icon Data-binding only possible with coding
Minus icon Only one function needs to manage all intents which can can get messy
Minus icon Google APIs only free Firebase connection
Minus icon Text responses merely a fallback as response must be constructed in the function

While the actual interface to create intents or deploy the chatbot are all as simple as could be, on balance you need to budget for the overhead of having to write hardcore code and debug every single API before you get much mileage out of your chatbot. And if you want to deploy your chatbot somewhere that isn't Slack or Facebook, you might find it difficult.

Trying to decide which chatbot is right for your team or organization?
We've created a series of guides and teardowns of different chatbot-building platforms. Learn how to scope out workplace-related use cases, or view all our guides on the adenin blog.

Author portrait

Article by Henry Amm

I’m the Senior Director for the Digital Assistant Platform. Prevously gained 6 years of experience as an Intranet consultant. Fluent in German.

Sponsored The #1 way to integrate work apps into SharePoint Get the free web part that connects to your workplace tools in minutes Try it free
Author portrait

Article by: Henry Amm

I’m the Senior Director for the Digital Assistant Platform. Prevously gained 6 years of experience as an Intranet consultant. Fluent in German.

Join the discussion

Avatar placeholder
This field is required.
This field is required.
This field is required.

0 responses

Be the first to leave a comment!