Google Dialogflow’s Golang Tutorial
I will start by saying that Google’s Dialogflow Fulfillment feature is great. Fulfillment makes easy building cool chatbots that can interact with our backend systems but sometimes this will not be enough.
In my case, I have built a chatbot core engine for Marvik.ai in Golang that handle’s context, conversation flows, etc. and that can also connect to multiple platforms such as Facebook Messenger, Telegram, Slack and more. It can use IBM Watson, Microsoft LUIS and Facebook Wit but I wanted to add Google Dialogflow. With this I can build different flexible and scalable bots in minimum time. Doing this I found some problems with Dialogflow that were not entirely well document so I have made this post to try to help others facing the same problem.
With Fulfillment you can build architectures such as this:
But following this tutorial, you will be able to build more complex and flexible ones such as this:
This is good because you can scale this (as we did) to build cool stuff like this:
In this tutorial I will assume that you are already familiar with Dialogflow and chatbots and will not go over some basic concepts.
If you don’t want to read the entire tutorial you can always just go to the code in Github following this link.
First, let’s create our chatbot’s intents and entities. If you don’t know how to do that I suggest you read other posts out there. Our bot will be focused on e-commerce and will allow us to check an order’s status given an Order ID. We will handle CheckOrderStatus intent for that with a numerical entity called OrderID.
Let’s see our intent’s entities:
Now let’s take a look at the configuration:
Once in the Configuration, click in the Service Account link shown below:
That will take you to Google’s Cloud Platform panel. Verify that you are in the Service Accounts tab and create a new service account pressing the button shown below:
Select a name for our service account, this will be for our use only:
Once you have the name, press the Create button. Then you will be prompted for the account roles. Search and select Dialogflow API Client. You could select others but this will be enough for us at this moment:
Once you’ve done that it will look like this. At this point press Continue:
Following step will look like this. Just press Create Key.
A pop up will appear. Just select the JSON option and press Create once more. This will download a JSON file (don’t lose it!):
Save the file into your project’s directory (or wherever you want, just remember the path to the key, we will need that later):
Now lets focus on our Golang code. Start by creating a simple Golang server. There’s no magic here, just listen to POST request on port 5000. We’ll expect a field called Message with the user’s input:
We’ll define a few structs that will be useful later. At this point we’ll import Google’s Dialogflow v2 library.
DialogflowProcessor will be used for handling all of our params and NLPResponse will be used to answer POST requests.
Notice how we have also defined a variable called dp of the type DialogflowProcessor (that’s outside of the main method).
We’ll need to initialize our communication with Dialogflow. We will use an init method for doing that. The Dialogflow’s project ID, language, timezone and path to the JSON key will be inputs for this. Variable dp will be populated at this point. We will define a context (ctx) and authenticate using the JSON key we have created and downloaded. This will create a session client that we will store in our dp variable.
Now let’s define a processNLP function that will recieve a raw message and will output the struct that we’ve defined above with the detected intent, confidence and list of entities.
We will use Google’s libraries for doing all of this so we will import a few new libraries. Notice how we are using dp variable with everything that we’ve defined above.
We will use an auxiliary function for extracting the entities. We will need to handle every single entity type that we are expecting in a switch depending on the input’s type. In this code we’ll just convert everything into a string for later use.
This code can be expanded to understand other entity types. For the above we will need to import a few other libraries. Resulting imports will be:
Now let’s redefine our main method so we can setup everything that’s needed before starting our server. First input is the project’s name (that’s read from Dialogflow’s configuration), second input is the path to the JSON file, third is the language code (en in our case for English) and last is our timezone.
And let’s redefine our request handler so we can use Dialogflow to understand input messages:
We will just answer the NLPResponse struct that we have defined. We are using testUser as a dummy but this should be replaced for an identifier for your users.
Now let’s test this from Postman. Build and run your Go code and open Postman. Do a POST request to your localhost 5000 port like this:
Awesome, it works! We input a raw message and we output the intent and confidence after our server queries Dialogflow.
Also, notice how we can extract entities in more complex inputs:
We have built a server that can be used as a microservice in our system. It receives raw messages and communicates with Dialogflow (handling all authentication necessary) and outputs the intents and entities.
Remember you can find this code (and sample chatbot) in this Github.