Get user permission for Google Action with node.js and cloud function
I was attending Govhack Victoria 2018 this year and our team decided to utilise the power of Google Action to build a navigation optimisation chatbot. The first problem I encountered was how do I get the users’ location and users’ name. To my surprise, most of the tutorial I found was outdated and some of the code just simply didn’t work anymore( I suspect Google just recently changed the API). So I decided to share what I learnt.
Package Required
const { dialogflow, Permission } = require('actions-on-google');
const app = dialogflow({ debug: true });Actions-on-google is a rich NPM client package to easily create interactions with Google Action. We first get a dialogflow class to initialise an app instance. This app has an intent() function that will be used to respond to each intent (More on this below). The Permission class required in the first line will be used to initialise a permission object that contains what info we want from the user and then will be sent back to the user for those specific permissions.
Register handlers for Dialogflow intent
There will be 2 intents in our case:
- Asking for users’ permission.
- Once the user permits, receiving users’ information.
Ask Permission
1 app.intent('Ask Permission', (conv) => {
2 const options = {
3 context: 'To locate you',
4 permissions: ['NAME', 'DEVICE_PRECISE_LOCATION']
5 };
6 conv.ask(new Permission(options));
7 });Here we utilise app.intent() function to add handlers for the intent called ‘Ask Permission’. This method will pass in a Conversation object to the handler callback. Conversation object has an ask() function and whatever is passed in this ask() function will be returned back to the user (line 6). And by passing a newly instantiated Permission object, we will hand over the conversation flow to google assistant for it to complete its task (in our case, get users’ info). Permission class takes an object that can specify
- context: A string that will be spoken to the user before the sentence that asks for permission. For example, in the above case, google action will return “To locate you, I’ll just need to get your name and current location from Google. Is that ok?”
- permissions: An array that contains all the permissions we want from the users. There are 5 permissions you can specify. Here we want the user’ name, their latitude and longitude.
Receive Permission
1 app.intent('Receive Location', (conv, params, confirmationGranted) 2 => {
3 const { name } = conv.user;
4 const { coordinates } = conv.device.location;
5 const latitude = coordinates.latitude;
6 const longitude = coordinates.longitude;
7 if (confirmationGranted) {
8 if (name) {
9 conv.ask(`Thanks ${name.display}. Where do you wanna go
10 today?`);
11 }
12 }
13 });After asking for a permission, when the user replies with a yes, google action will send out an event to the dialogflow: action_intent_PERMISSION

What is an event? An event is another way to trigger an action besides matching a user’s input query. Once this happened, it will send a webhook for your logic that is dealing with this intent. In the same callback function in intent() function (line 1), we now can access username, user location from Conversation object (line 3–6).
Save data in Conversation
Often time, you will want to save users’ location and name between turns of the conversation so that you don’t have to ask for users’ permission every single time. You can use userStorage to do that:
conv.user.storage.latitude = latitude;
conv.user.storage.longitude = longitude;In this case, we can save the precise location of the user to be reused later.
Firebase Cloud Function
Now if you want these code to start working, the fastest way is to use the firebase cloud function. Firebase cloud function is simply the function that is the cloud lol! It will allow you to solely export a function that is dealing with all the intent to the cloud and once a intent is matched, it will send a webhook to that cloud function and get the response. This saves a huge amount of time compared to you trying to deploy a server or use Heroku for a simple task like this. There are only 2 steps you need to do:
1 const functions = require('firebase-functions');
2 exports.dialogflowFirebaseFulfillment =
functions.https.onRequest(app);First, we required the firebase function package. Second, we pass our previous app to the functions variable we just required and export it as ‘dialogflowFirebaseFulfillment’ to the cloud.
Conclusion
In this post, I shared how to add intents to get users’ permission, how to store state between turns of the conversation and how to start using cloud function. Thanks for reading and be ready for more posts!
Peace out!