Google Dialogflow with Fulfillment, Webhook and Python Flask!

Marcus Yatim
10 min readJun 15, 2021

So I did a story previously introducing Dialogflow and how to use it to create a basic chatbot on Telegram.

And we only scratched the surface of the potential of Dialogflow, the proverbial tip of the iceberg. Today, we shall get to the advanced stuff and explore fulfillment and webhook. Understanding what these do will be akin to having an oxygen tank to dive under the ocean and explore the rest of the iceberg. Bet it’s the first time you’re hearing that analogy.

As always, I have an accompanying YouTube tutorial, for those of you visual and audio learners.

Be sure to Like and Subscribe!

What is fulfillment and webhook

Fulfillment and webhook allows us to work with our own code, which may contain a variety of functions to improve the chatbot. You may also have realised that Dialogflow does not have a build-in IDE. Therefore, we have to import our code from our computer. To do this, we need to enable fulfillment in Dialogflow to let it know that we are going to read in an external code script and to use it. This begs the question:

“How are we going to let our code reach Dialogflow?”

The code script is on our computer while Dialogflow is hosted on Google’s servers and these are obviously two completely separate environments. That’s where webhook comes in. We will upload our code online onto a server and webhook tells Dialogflow where to read this code online from said server.

Case Study

To demonstrate the above, we’ll look at a case study I did on the Travelling Saleman Problem. I have a video on this as well for you to check out.

Be sure to Like and Subscribe!

It is 30mins long so I’ll give a summary of it:

We shall imagine ourselves as a startup food catering business. We have an intelligent system that reads in a set of destinations and gives us a route that is optimised to either be of shortest distance or shortest time duration required to make it from our kitchen to every destination and back to our kitchen.

To make the system even more convenient, we shall create a Telegram chatbot for it. Our chatbot will allow the user to type in all the addresses of the destinations and once done, it will output the optimised routes.

Dialogflow

Intent to get addresses

Let’s start by creating an intent to do exactly that. For the training phrases, throw in a bunch of made up addresses. You do not have to give proper addresses because there’re too many variations in the whole wide world. Our purpose is to instead train the system to simply recognise and pick out the whole input string. This has an assumption: the user will only type the address of the destination and nothing else. That means that the user should not type something like “My address is such-and-such”. We just want the address.

Notice the entire phrase is highlighted because we want Dialogflow to recognise that the whole string will be the address. In fact, these are being assigned an entity. There are system entities that are related to locations, however, we want to make it as generalised as possible so we’ll use the ‘@sys.any’ entity. This entity is most useful for making general references. We shall also name them as the ‘address’ parameter and name the action as ‘get.address’.

Get-Addresses response

For our response, we will not fill it up in the Dialogflow console. Instead, it will be created from our code. A response from a given code will supersede that which is written in the console’s text box. Also, remember that our code is meant to be on a server? Assuming Dialogflow is unable to access the server or the code for some reason, then Dialogflow will fall back to the response that is given in the text box here. Therefore, the response I have written in the text box is “Server Offline”. Hence, if I see this response in the chatbot, I will know that the code was not executed.

Python Flask

We will use Python in our code and to execute it for our chatbot, we need to use a special Python library. This is because we are writing code that will go up into a server and this requires a special format. To achieve that, we use Python Flask. Python Flask is a specialised API library that can be used for web development. If you’ve never used Python Flask before, I would recommend you check out this quickstart documentation.

Python Flask skeleton code

On the left is a basic skeleton of the Python Flask code that we will use for our chatbot. This skeleton code can be used not only for our tutorial today, but for ANY chatbot. In line 8, you can choose to rename “/webhook” to any name you want (the backslash has to remain). You’ll see how this part fits in towards the end, but for now we’ll leave the name as it is.

Diagnostic Info

In line 10 we come across a request. A request is what the user types into the chatbot to expect a response. If you type something into the chatbot and click on “DIAGNOSTIC INFO” at the bottom, you can see how the user’s request is shown in JSON format.

In line 11, we initialise the fulfillment text. A fulfillment text is the same as a Response in the Dialogflow console.

In line 12, we retrieve the query result. The query result is found from line 3 onwards of the ‘Diagnostic Info’. It tells us everything we need to know about what the user has typed. For example, the text that was typed is “abc mart”. The action called is “get.address”. The parameter referenced is “address”.

In line 13, we are looking to see if the “action” key matches “get.address”. We can also match other keys such as the “queryText” or “parameters”, based on our needs. Of course, we can have as many if-else statements as required to match our Dialogflow intents. Once matched, we can define a set of executable code inside the if-else statement and create different fulfillment texts.

And finally, in line 20, we will return the fulfillment text back to Dialogflow for it to print out the response.

Fulfillment enabled

Let’s return to Dialogflow and ensure that all the intents that are to be involved with the code have the “Enable webhook call for this intent” option enabled, under ‘Fulfillment’.

Transferring your code onto a server

Next, we have to transfer our code onto a server. To do that we want a service that provides a server. There are many services of such and while most of them are paid, more often than not, they also provide a free tier that we can use. Today, we will be using Heroku.

But before we get to that, we should also discuss running our code on a localhost. What this means is that the code will be hosted on your own local network and most often can be done free of charge. You might ask:

“Why use a paid service when I can use localhost?”

Well, there are important distinctions to the both of them. First, if you want to run localhost continuously, you have to leave your computer turned on continuously as well. That means if you turn your computer off, your localhost will terminate and your chatbot will not be able to read its code. This is fine if you’re doing a mini school project or some sort, but obviously if you want to scale it up and have a proper chatbot that works 24/7, then this isn’t the best solution.

The reverse argument can then be made:

“I should always use the paid service, or the free tier of it at the very least. Why do I need to know about localhost?”

It is still useful for you to use a localhost in order to develop and test your code. We always test our code on a development environment and not on the production level. If you’re using a paid service to test your code and mind you, testing often involves many trials of running and changing your code, you will incur all the charges that comes with the paid service. Even if you’re using a free tier, more often than not, these free tiers come with a limited amount of free access. We don’t want to use it all up just by doing testing.

ngrok

In order to run localhost, we shall make use of ngrok — a tool that offers free running of localhost. Ngrok also has their own paid servers, albeit not with a free tier. Hence, we shall only use ngrok for our testing environment on the localhost. Additionally, we will use Heroku for our free tier servers for the production environment.

Sign up for an account and download ngrok @ https://ngrok.com/. Once done, run the application and issue the command:

ngrok http 5000
ngrok

What has happened now is that ngrok has created a tunnel that forwards all requests going to the temporary unique Forwarding URL, to your localhost port 5000. Copy the forwarding URL and note that we want the second one listed as Dialogflow only accepts https and not http.

Webhook

Insert the forwarding URL into your Dialogflow ‘Webhook’ under the ‘Fulfillment’ section and click save. Now, when a user types into the chatbot, Dialogflow will send the request to the URL and ngrok will forward it back to our localhost. One more thing to note is the “/webhook” at the end of the URL. This looks familiar and it should because it was defined as the webhook route in our code.

Running Python Flask locally

We have just linked Dialogflow to our localhost. Now we shall also link our code to the localhost, so that Dialogflow and the code can interact together. Flask has got us covered on that.

Running Flask

Referring to the Flask quickstart documentation, we need to tell the terminal the name of our Flask app and then we can execute Flask. Notice that it will run on port 5000 and that is the same port as Dialogflow.

Using Heroku for Production

Let’s assume we have completed testing of our code and we want to deploy it to production. This time we’ll need the Heroku server. Sign up for a Heroku account @ https://heroku.com and then create a new app.

Domain name

Go under settings to find your domain and copy and paste it into your Dialogflow webhook. Don’t forget to append “/webhook” at the end of the URL.

We have just linked Dialogflow to Heroku, now we have to transfer our code to Heroku as well. This requires you to be familiar with Git because we will use Git to upload our code onto the Heroku server.

First of all, ensure your code is in its own individual folder. We then have to add in a couple of new files to the folder. The first file is ‘requirements.txt’. Inside it, we define the libraries that our application uses. This is because our Heroku app is a completely new environment, so just like we had to install the libraries to be used locally on our computer, we have to let Heroku know what are the libraries it needs to install.

requirements.txt

Inside the file, we will add in the names of the libraries to be installed and also their versions. We also need to install ‘gunicorn’. Gunicorn is a library that tells Heroku to start a web server for our flask application. To enable gunicorn, we do not call it via a Python script. Instead, we want to create the second new file: Procfile. First, simply create a .txt file. Inside it, type in:

web: gunicorn name-of-flask.app

Where ‘name-of-flask’ is the name of your Flask application. Save it, rename the file as ‘Procfile’ and remove the .txt part of it. Indeed, this file will not have any extensions.

Now, we shall upload all of these onto Heroku. First, go to your terminal and change the directory to the folder where all the code is. Then, we shall initialise it for git with:

git init

We then git add the files that we have with:

git add .

(note the period symbol at the end. This indicated to git that we are including ALL the files in the folder).

Next, git commit them with a message of your choice:

git commit -m "heroku commit"

Then, we need to login to our Heroku app. Type in your terminal:

heroku login

This will open the browser to login to your Heroku account.

Then, while logged in, we need to link the Heroku repository with our local one:

heroku git:remote -a name-of-app

Where ‘name-of-app’ is the name of the app you created in Heroku.

After we’re done, we git push our code onto Heroku:

git push heroku master

Congratulations! You have successfully deployed Heroku for production. Your chatbot should work 24/7 with your code if you have completed the steps correctly.

Conclusion

We have covered the necessary steps required in order to enable fulfillment and webhook with Dialogflow and this will now allow you to code exciting features for your chatbot. The steps involved here are the backbone for any chatbot project you embark on. The Python Flask skeleton code is also reusable for most chatbot projects.

For the skeleton code, refer to my github @ https://github.com/marcusyatim/dialogflow-webhook-tutorial

And with that, I wish you, kind reader, all the best in your coding!

--

--

Marcus Yatim

Innovator. Challenging the norms. Avid content creator.