# Account Linking in Actions on Google

*In this article, you learn how to link your Google account to Google Assistant action using Dialogflow and Cloud Functions*

### Overview

In this article, you learn how to link your Google account to Google Assistant action using Dialogflow and Cloud Functions

### Objectives

1. What is Google Assistant
    
2. What is Cloud Function
    
3. Create a new action in Google Assistant
    
4. Account Linking
    
5. Create a custom action using Dialogflow
    
6. Adding Fulfilment logic to Cloud Function
    
7. Test your action
    

### Prerequisites

* Google Cloud Account
    
* Pair of headphones or turning the volume up on your computer is recommended.
    

### 1\. What is Google Assistant

[Google Assistant](https://assistant.google.com/#?modal_active=none) is a personal voice assistant that offers a host of actions and integrations. From sending texts and setting reminders, to ordering coffee and playing music, the 1 million+ actions available suit a wide range of voice command needs.

### 2\. What is Cloud Function

[Google Cloud Functions](https://cloud.google.com/functions/docs/) is a lightweight compute solution for developers to create single-purpose, stand-alone functions that respond to Cloud events without the need to manage a server or runtime environment.

### 3\. Creating a new action in Google Assistant

Regardless of the Assistant application, you’re building, you will always have to create an Actions project so your app has an underlying organizational unit.

Open the [Actions on Google Developer Console](http://console.actions.google.com/) in a new tab. You should be looking at a clean Actions console that resembles the following (If you are a new user (:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056536364/dd92d57f-eb9e-4697-9aa9-384396063bfa.png align="left")

Actions on Google Console

Click **Add/import project** and agree to Actions on Google’s terms of service when prompted.

Click into the Project Name field and add the project name **account day**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056538096/52b7ba51-ec3b-458d-985f-47d1c05f89b2.png align="left")

Adding project name

Once the project is created you will see a welcome screen like below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056539682/f59fb3e7-ba8a-457d-a3a3-effd956f2cb0.png align="left")

Now click **Actions on Google** in the top left corner to return to the homepage. Then click on the project you just created

### 4\. Account Linking

Select the **develop** tab and on the left-hand side select the **Account Linking** option like below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056541170/564353cc-52fa-4294-8782-cb93044768ed.png align="left")

Account Linking

Click **Yes to sign up** for new accounts via voice and click **Next**

Now select the Linking type as **Google Sign In**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056542707/d745351a-f8fa-442f-a8f8-7960f1eb2e8d.png align="left")

Now you will get the Google Sign-In Client Information like below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056544200/957470a3-3757-4efe-a252-7f4d55487501.jpeg align="left")

Google Sign-In Client Information

copy the credentials you will be using it in your cloud function and click **Save**

> If your action is select for family-friendly apps then you can’t use the Account Linking option

### 5\. Creating a custom action using Dialogflow

Now we will create a custom action using Dialogflow from the left-hand menu, select **Build &gt; Actions &gt; Add your first action**. Then select **Custom Intent &gt; BUILD**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056545945/3a771404-d0a1-49f6-bd3d-6c337f9a8d5c.png align="left")

Custom Intent

This will take you to the Dialogflow console.

Click **Allow** when Dialogflow prompts you for permission to access your Google Account.

When you land on the Dialogflow account settings page, check the box next to **Yes, I have read and accept the agreement** and click **Accept**. You will now be brought to a Dialogflow agent creation page. Click **CREATE**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056547459/34800489-37a6-4644-81fd-ed3e1d727628.png align="left")

Dialogflow agent creation

An [agent](https://dialogflow.com/docs/agents) is an organizational unit that collects information needed to complete a user’s request, which it then forwards to a service that provides fulfillment logic.

You will now build the basic framework for fulfillment logic. This will be handled (later) by a Cloud Function, which will return a response to link your Google Account for the action

Click **Fulfillment** from the left-hand menu. Move the slider for **Webhook** to the right, setting it to **Enabled**.

Now enter the temporary URL `https://google.com` in for the URL field. You will update this URL when you build your Cloud Function. Your page should resemble the following:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056549030/9a472a37-f430-4f32-be24-229d25c2e1e7.png align="left")

Webhook

click **Intents from** the left-hand menu and select **Default Welcome Intent**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056550444/8add1606-ae08-43f8-9303-5de8685dbd87.png align="left")

Default Welcome Intent

Scroll down to the **Responses** section and click the **trash icon** to scrap all of the default text responses

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056551813/0843c789-61d5-4ee3-8391-8e7bc498299b.png align="left")

Default Responses

Now scroll down and select Fulfilment section and Enable webhook call for the intent

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056553063/5feffc51-6b6f-482d-b740-ae2d1d659315.png align="left")

Enable webhook

From the left-hand menu, click on the **+** icon by the **Intents** menu item. For the **Intent name** field, enter `Get Sign In`

Scroll down and select Events and type `Google Assistant Sign In`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056554481/827320c8-963a-46af-ba86-151382c795e2.png align="left")

Sign In Event

> Build better voice apps. Get more articles & interviews from voice technology experts at voicetechpodcast.com

Now scroll down and select Fulfilment section and Enable webhook call for the intent

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056555646/8a28a716-3aa8-4f26-b39b-98cd1a3782f4.png align="left")

Enable webhook

Now create one more intent by clicking the + icon from the left-hand menu and name it as **Give Color**

Scroll down and select the **Training Phrase** and add some training phrases like below

red is my favourite color  
i like blue  
set yellow  
yellow

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056557008/f8cf6d18-db58-4d8e-8b8d-1e4ccd914101.png align="left")

Color Intent

Now scroll down and select Fulfilment section and Enable webhook call for the intent

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1698056558202/d1d00f30-0470-4aff-b8fb-ceaa48d49768.png align="left")

### 6\. Adding Fulfilment logic to Cloud Function

Now we will create the firebase cloud function

Go to your local terminal and create a new directory named **account-day** and navigate to that directory

Once navigated initialize Firebase Cloud Function using the command `firebase init` and then select Cloud Function

Now Firebase CLI will ask you to select the project once the project is selected CLI will create the files like

* index.js
    
* package.json
    

Now install the `actions-on-google, dotenv, firebaseadmin, firebase-functions`plugin using the command

* `npm i actions-on-google`
    
* `npm i dotenv`
    
* `npm i firebase-admin`
    
* `npm i firebase-functions`
    

Once the plugins are installed open `index.js` in any text editor and remove the existing codes

Now we will import the dependencies needed for the plugin like below

```javascript
const {dialogflow, SignIn, Suggestions} = require('actions-on-google');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const dotenv = require('dotenv');
```

Initialize the firebase admin and dotenv

```javascript
dotenv.config();
admin.initializeApp();

const auth = admin.auth();
const db = admin.firestore();
db.settings({timestampsInSnapshots: true});
```

Create a new const variable and declare the clientid which you have copied earlier

```javascript
const app = dialogflow({
clientId: // add the clientid which you have got earlier
});
```

Create a new Default Welcome intent like below

`app.intent('Default Welcome Intent', async (conv) => {});`

Add a sample response to the default welcome intent like below

```javascript
app.intent('Default Welcome Intent', async (conv) => {
conv.ask(new Suggestions('Red', 'Green', 'Blue'));
conv.ask(`What's your favorite color?`);
});
```

Now when the user selects the color we will invoke the Give Color intent with Sign-in option

```javascript
app.intent('Give Color', async (conv, {color}) => {
conv.data[Fields.COLOR] = color;
conv.ask(new SignIn(`To save ${color} as your favorite color for next time`));
});
```

Now it will open the Get sign-in intent like below

```javascript
app.intent('Get Sign In', async (conv, params, signin) => {
if (signin.status !== 'OK') {
return conv.close(`Let's try again next time.`);
}

const color = conv.data[Fields.COLOR];
await conv.user.ref.set({[Fields.COLOR]: color});
conv.close(`I saved ${color} as your favorite color. ` +
`Since you are signed in, I'll remember it next time.`);
});
```

In the above snippet, we will check whether the user has given access to sign in if not it will return try again next time option

Once the sign-in is successful we will get the user profile data from firebase auth as well as in Firestore database

For that, we will be using middleware like below

```javascript
app.middleware(async (conv) => {
const {email} = conv.user;
if (!conv.data.uid && email) {
try {
conv.data.uid = (await auth.getUserByEmail(email)).uid;
} catch (e) {
if (e.code !== 'auth/user-not-found') {
throw e;
}
// If the user is not found, create a new Firebase auth user
// using the email obtained from the Google Assistant

conv.data.uid = (await auth.createUser({email})).uid;
}
}
if (conv.data.uid) {
conv.user.ref = dbs.user.doc(conv.data.uid);
}
});
```

In the above code will check whether the user email is present or not and if available will get the user Uid from Firestore

Now in the **Give Color** intent, we will add the condition to get the user details

```javascript
app.intent('Give Color', async (conv, {color}) => {
conv.data[Fields.COLOR] = color;
if (conv.user.ref) {
await conv.user.ref.set({[Fields.COLOR]: color});
conv.close(`I got ${color} as your favorite color.`);
return conv.close(`Since you are signed in, I'll remember it next time.`);
}
conv.ask(new SignIn(`To save ${color} as your favorite color for next time`));
});

```

Now we will add the condition to check whether the user is logged in or not in the **Default Welcome Intent**

```javascript
app.intent('Default Welcome Intent', async (conv) => {
if (conv.user.verification !== 'VERIFIED') {
return conv.close(`Hi! You'll need to be a verified user to use this sample`);
}
conv.ask(new Suggestions('Red', 'Green', 'Blue'));
conv.ask(`What's your favorite color?`);
});
```

Now in the **Default Welcome Intent**, we will add the condition to get user profile details as well as the color that the user has said like below

```javascript
app.intent('Default Welcome Intent', async (conv) => {
// Account Linking is only supported for verified users
// https://developers.google.com/actions/assistant/guest-users
if (conv.user.verification !== 'VERIFIED') {
return conv.close(`Hi! You'll need to be a verified user to use this sample`);
}

const {payload} = conv.user.profile;
const name = payload ? ` ${payload.given_name}` : '';
conv.ask(`Hi${name}!`);
conv.ask(new Suggestions('Red', 'Green', 'Blue'));

if (conv.user.ref) {
const doc = await conv.user.ref.get();
if (doc.exists) {
const color = doc.data()[Fields.COLOR];
return conv.ask(`Your favorite color was ${color}. ` +
'Tell me a color to update it.');
}
}

conv.ask(`What's your favorite color?`);
});
```

Now go to **Firebase console** and select the project you have created in AoG and **Go to settings** &gt; **Service accounts** &gt; **Firebase Admin SDK** &gt; **Node.js** &gt; Generate the new private key

Once the private key is downloaded rename it to `service-account.json`

In the Firebase console click **Database** and select **Firestore** database and click start in test mode

Now deploy the cloud function using the command

`firebase deploy--project {PROJECT_ID} //get the PROJECT_ID from Dialogflow console settings`

Copy the webhook URL once it is deployed and paste the webhook URL in Dialogflow

### 7\. Test your action

Once added test your application you will get the output like below as well as a confirmation email to the email id which you have tried to login

<iframe src="https://www.youtube.com/embed/xa9ykQbgCF8?feature=oembed" width="700" height="393"></iframe>

Feel free to grab the source code for the cloud function

### Resource Links

* AoG Resource — [https://developers.google.com/assistant/identity/google-sign-in#nodejs](https://developers.google.com/assistant/identity/google-sign-in#nodejs)
    
* AoG Nodejs-Github — [https://github.com/actions-on-google/dialogflow-google-sign-in-nodejs](https://github.com/actions-on-google/dialogflow-google-sign-in-nodejs)
    

### Congratulations!

You have learned how to link your Action with Google Account. Happy Learning :)
