How to Setup DialogFlow V2 Authentication Programmatically with node.js
A week ago, DialogFlow, my favorite platform for building chatbots, announced the general availability of V2 API. As a developer who got used to working with V1 I was initially reluctant to migrate to V2 but eventually decided it’s worth the effort. Why? 3 main reasons:
- V2 is now the default API version. All new features will only be supported for that version, making V1 increasingly useless
- Audio queries support via Google’s voice to speech
- Dialog Enterprise Edition supports V2, and, while it may not be immediately relevant, hopefully, once your chatbot becomes popular, you’d need more scalability and better support which the enterprise edition provides
If you already develop with DialogFlow and started to follow the migration guide, you should know by now what a pain in the a$$ it is. My goal in this article and the next ones is to save you some of the time and frustration I had to incur.
So today we’re going to see how to switch from the ever-so-easy V1's client token to the tricky V2’s service account.
Before we start
Please make sure to export your existing agent. If something goes wrong, you could always go back to your good old V1 agent. Click on the gear icon near your agent’s name, ‘Export and Import’ tab and click the ‘EXPORT AS ZIP’ button.
Setting up Authentication
In V2, DialogFlow embraces the concept of service accounts and abandons V1’s client access token. Although service accounts are preferable over access tokens, there’s a somewhat steep learning curve when it comes to creating and deploying them.
Now, you could follow DialogFlow Authentication setup guide but I found it to be inconsistent with what happens in practice in your console. So, here’s how I do it:
- Go to your agent’s settings. You should already have a Google Project linked to your Agent. If you don’t, click on the ‘Create or link existing Google project id’ link. Then, in the dialog window that opens up, click on the ‘Create a new Google Project’ dropdown arrow and create or choose an existing project. Please note that once a project is linked to or created, it can not be changed. If you wish to use another project, you’d need to create a new agent. However, since you followed the ‘Before we start’ instructions above and exported your agent, it should be as easy as a pie. You did follow the instructions, right?
- Back in agent’s settings, under ‘API VERSION’, select ‘V2 API’. You should see a dialog similar to the one below. Click on ‘UPGRADE TO V2’
Setting up Service Account
Now you need to create the service account, or, more precisely, its key. Again, in the settings, click on blue ‘SAVE’ button at the top right. The button will change to a green ‘WORKING…’ button. After it finish, you should see a service account field right underneath the project’s name
Click on the service account name. This will open your Google Cloud Platform project’s service account page. You should see the ‘Dialogflow integrations’ service account that was just created:
Next step is to create a new key for the service account (the one that’s already there in useless and you could delete it after we finish). Click on the 3 vertical dots at the far right and choose, you guessed it, ‘Create Key’. Keep the JSON key type option and hit ‘CREATE’. A JSON file will be downloaded to your computer and you’ll see a message “Private key saved to your computer”. Click on ‘Close’. You’re almost there! It’s time to move to the code!
Bonus Tip
The default role for your service account is that of ‘Dialogflow API client’. That should be enough in most cases, unless you need to fetch and edit intents and entities programmatically (which you would if you wish to cleverly handle fallback intents for example — more on that in next post), in which case you’d need an admin role.
Let’s do some coding!
OK, so, Dialogflow/Google recommend using their gcloud SDK and cli and then store the JSON file you just loaded in a secure place and set an environment variable GOOGLE_APPLICATION_CREDENTIALS pointing to the location of the file.
I find this very convoluted and in contrast to my personal development practice of:
- I only deploy code files
- Any configuration values should be set as environment variables.
This means we should use an alternative to the JSON file. OK, tl;dr, here’s the code I use:
Unlike Dialogflow SDK example, I instantiate a SessionClient with a config object. All that object needs is the private_key and client_email. You can find their values in the JSON file you just downloaded (which, you can now delete as you don’t need it anymore). Just copy them to your favorite configuration module and you’re good to go.
Now, all you need to do to identify an intent from a given text input is to call:
let responses = await this.sessionClient.detectIntent(request)
and that’s it!
Bonus Tip
You may have noticed that I either JSON.parse(private_key) or use private_key as is. The reason being that on my local windows machine (don’t judge me), the string works just fine. However, on Heroku, the \n(ewline) confuses it (see more here).
Hope you enjoyed the post!