Actions on Google is a developer platform that lets you create software to extend the functionality of the Google Assistant, Google's virtual personal assistant, across more than one billion devices, including smart speakers, phones, cars, TVs, headphones, and more. Users engage Google Assistant in conversation to get things done, like buying groceries or booking a ride (for a complete list of what's possible now, see the Actions directory.) As a developer, you can use Actions on Google to easily create and manage delightful and effective conversational experiences between users and your own 3rd-party service.

This is an advanced codelab module, intended for readers who already have some experience building Actions for the Google Assistant. If you don't have any prior development experience with Actions on Google, we strongly recommend that you familiarize yourself with the platform by following our introductory codelabs (Level 1, Level 2, and Level 3). These advanced modules will guide you through a series of features that can help you expand your Action's functionality and grow your audience.

One important way we measure an Action's success is user engagement, or how effective the Action is at bringing users back after their first interaction. To help make this easier, we have several features you can implement in your Action that give users paths back into your conversation. This codelab covers user engagement features and best practices for Actions on Google.

What you'll build

In this codelab, you'll add the following features to a pre-built Action:

What you'll learn

What you'll need

You must have the following tools to complete this codelab:

Familiarity with JavaScript (ES6) is strongly recommended, although not required, to understand the webhook code used in this codelab.

For this codelab, you'll add user engagement features to a complete, pre-built Action.

Understand the sample

The sample for this codelab is a simple Action for a fictional gym named "Action Gym". This Action provides information about the gym, including a list of classes that rotate out each day. This type of informative Action is a good candidate for all user engagement features, since the rotating class list gives different useful information each day.

The Action Gym sample's conversation will start out like the following diagram:

Throughout this codelab, you'll make minor modifications to the dialog to better suit the engagement features we've added, but the general design of the conversation won't change much.

Download your base files

Run the following command to clone the GitHub repository for the codelab:

git clone https://github.com/actions-on-google/user-engagement-codelab-nodejs

Set up your project and agent

To set up your Actions project and Dialogflow agent for this codelab, complete the following steps:

  1. Open the Actions console.
  2. Click on Add/import project.
  3. Type in a Project name, like engagement-codelab.
  4. Click Create Project.
  5. Rather than pick a category, scroll down to the More options section and click the Conversational card.
  6. Click Build > Actions in the left navigation and click Add Your First Action.
  7. On the Create Action dialog, select Custom Intent, and then click Build to launch the Dialogflow console.
  8. In the Dialogflow console's agent creation page, click Create.
  9. Click the (gear icon) on the left navigation.
  10. Click Export and Import, then Restore From Zip.
  11. Upload the agent.zip file from the /user-engagement-codelab-nodejs/start/ directory you downloaded earlier.
  12. Type RESTORE and click Restore.
  13. Click Done.

Deploy your fulfillment

Now that your Actions project and Dialogflow agent are ready, deploy your local index.js file using the Firebase Functions CLI.

From the /user-engagement-codelab-nodejs/start/functions/ directory of your base files clone, run the following commands:

firebase use <PROJECT_ID>
npm install
firebase deploy

After a few minutes, you should see "Deploy complete!", which indicates that you've successfully deployed your webhook to Firebase.

Retrieve the deployment URL

You need to provide Dialogflow with the URL to the cloud function. To retrieve this URL, follow these steps:

  1. Open the Firebase Console.
  2. Select your Actions project from the list of options.
  3. Navigate to Develop > Functions on the left navigation bar. If you're prompted to "Choose data sharing settings", you can ignore this option by clicking Do this later.
  4. Under the Dashboard tab, you should see an entry for "fulfillment" with a URL under Trigger. Save this URL; you'll need to copy it into Dialogflow in the next section.

Set the webhook URL in Dialogflow

Now you need to update your Dialogflow agent to use your webhook for fulfillment. To do this, follow these steps:

  1. Open the Dialogflow console (you can close the Firebase console if you'd like).
  2. Click Fulfillment on the left navigation.
  3. Enable Webhook.
  4. Paste the URL you copied from the Firebase dashboard if it doesn't already appear.
  5. Click Save.

Verify your project is correctly set up

Users should be able to invoke your Action for information about Action Gym, including a hard-coded text response with business hours and a text response that lists the class schedule for each day of the week.

To test out your Action in the Actions simulator:

  1. In the Dialogflow console left navigation, click on Integrations > Google Assistant.
  2. Make sure Auto-preview changes is enabled and click Test to update your Actions project.
  3. The Actions simulator loads your Actions project. To test your Action, type Talk to my test app into the Input field and press enter.
  4. You should see a response welcoming you to Action Gym. Try following the prompts to continue the conversation while making sure that your fulfillment has a response for each input.

A common way to engage users is to offer information to them when it's most useful. This is accomplished by offering users the option to subscribe to daily updates for an intent, which sends them an Assistant notification that links directly to that intent's fulfillment.

In this step, you'll learn about daily update subscriptions and add them to your Action's Class List intent. After following these instructions, your Action's conversation will look like the following diagram:

How will this engage users?

Smartphone users are probably familiar with push notifications, which provide app-specific information and updates. Daily update subscriptions are a simple way to access users on mobile devices outside of the Assistant, provided that the intent you're sending updates for continues to provide value to the user on a daily basis.

Daily updates can be a useful engagement tool but should not necessarily be incorporated in every Action. Consider these tips when deciding whether to add daily update subscriptions to an Action:

Turn on daily updates

Daily update subscriptions can be added to the welcome intent which puts the user at the start of your conversation, or a more specific intent in order to deep link them to somewhere within the conversation. For this codelab, the Class List intent makes the most sense because the dialogue will change every day, and users may find it useful to be reminded what classes are available.

Follow these steps to enable daily updates for the Class List intent:

  1. In the Actions console, go to Build > Actions in the left navigation bar.
  2. Click on Class List under the Actions list.
  3. Under the User engagement section, toggle the Would you like to offer daily updates to users option.
  4. Set a descriptive Content title that describes the daily update. The context will be "What time would you like me to send your daily <content title>", so make sure your title is both descriptive and sounds correct when spoken aloud. For this example, set the Content title to list of upcoming Action Gym classes.
  5. Click Save at the top of the page.

Set up Dialogflow

Follow these steps in the Dialogflow console to create intents for the daily update subscription flow:

Prompt the user to subscribe

  1. Set up a new intent to handle the user asking to subscribe to daily updates. In the Dialogflow console, click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Setup Updates.
  3. Under the Training phrases section, add the following user expressions:
  1. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  2. Click Save at the top of the page.

Handle the user's decision

  1. Set up a new intent to handle the user's response to the daily updates subscription prompt. Click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Confirm Updates.
  3. Under the Events section, add actions_intent_REGISTER_UPDATE. This Dialogflow event will be triggered by the user finishing the daily update subscription flow, whether they ended up subscribing or not.
  4. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  5. Click Save at the top of the page.

Implement the fulfillment

To implement the fulfillment in your webhook, complete the following steps:

Load dependencies

In the index.js file, update the require() function to add the RegisterUpdate package from the actions-on-google package, so your imports look like this:

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
} = require('actions-on-google');

Update suggestion chips

In the index.js file, add a DAILY entry to the list of suggestion chip titles, so your Suggestion definition looks like this:

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
};

Add fulfillment for new intents

When the user says they want to subscribe, start the daily updates subscription flow by calling the RegisterUpdate helper with the update's target intent (Class List) and type (DAILY). After the subscription flow is finished, the Assistant will trigger the actions_intent_REGISTER_UPDATE event with a status argument which describes whether the subscription was successful or not. Offer follow-up prompts to the user that change depending on the subscription status.

In the index.js file, add the following code:

index.js

// Start opt-in flow for daily updates
app.intent('Setup Updates', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'Class List',
    frequency: 'DAILY',
  }));
});

// Confirm outcome of opt-in for daily updates
app.intent('Confirm Updates', (conv, params, registered) => {
  if (registered && registered.status === 'OK') {
     conv.ask(`Gotcha, I'll send you an update everyday with the ` +
     'list of classes. Can I help you with anything else?');
  } else {
    conv.ask(` I won't send you daily reminders. Can I help you with anything else?`);
  }
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS, Suggestion.CLASSES]));
  }
});

Offer alternative prompts for the user

Your Class List response will offer the daily update subscription at the end, but this presents a problem. Since this same response will be triggered when the user taps the daily update notification, they'll still be asked to subscribe to daily updates even though they just came from one. How can you keep the user from thinking they need to re-subscribe?

Thankfully, your conv object's arguments include information about where the user started the conversation. You can check the conv arguments to see if they contain an UPDATES section, which indicates the user started the conversation from a daily update notification, and change the response accordingly. You can also use this conversation branch to close the dialog immediately after providing the list of classes, which follows our best practice of keeping the daily update short.

In the index.js file, replace the following code:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  const classesMessage =
  `On ${day} we offer the following classes: ${classes}. ` +
  `Can I help you with anything else?`;
  conv.ask(classesMessage);
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS]));
  }
});

with this:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

Test your daily updates

In the terminal, run the following command to deploy your updated webhook code to Firebase:

firebase deploy

To test out your custom reprompt in the Actions simulator, follow these steps:

  1. In the Actions console, navigate to Test > Simulator.
  2. Type Talk to my test app into the Input field and press enter.
  3. Type Learn about classes and press enter. Your Action's response should now offer to send daily reminders.
  4. Type Send daily reminders and press enter.
  5. Type in a time that you'd like to see the update and press enter. For testing purposes, try responding with 3-5 minutes later than the current time.

On your mobile device, you should receive a notification from the Assistant around the time that you specified for updates. Note that this notification may take a couple minutes to appear. Tap on the notification and it should deep-link directly to the Class List intent in the Assistant, giving you a list of upcoming classes:

As another option to engage users outside of your Action, you can call the Actions API to send push notifications to users. Unlike daily updates, these notifications aren't automatically scheduled by the Assistant so you can send them at-will.

In this step, you'll learn how to implement push notifications in your Action by adding a new Class Canceled intent and sending notifications to users that notify them about a class cancellation. You'll also set up the following three components needed to send notifications:

After following these instructions, you'll add the following dialog to your Action's conversation:

How will this engage users?

Smartphone users are probably familiar with push notifications, which provide app-specific information and updates. Push notifications are a flexible way to access users on mobile devices outside of the Assistant, provided that users are given a good reason to enable them. With daily updates, users are already aware that they'll be notified on a daily basis. With push notifications, however, users don't know whether they're opting in to receive infrequent notifications or will be pestered with multiple notifications per day.

Push notifications can be a useful engagement tool but should not necessarily be incorporated in every Action. Consider these tips when deciding whether to add push notifications to an Action:

Enable the Actions API

  1. Open the Google Cloud console and select your Actions project name in the dropdown.


  2. In the navigation menu (☰), go to APIs & Services > Library.
  3. Search for the Actions API, and click Enable.

Create a service account

The Actions API requires authentication so you need to create a service account to send requests. Follow these steps to create and install a service account key for the Actions API:

  1. In the Google Cloud Console's navigation menu (☰), go to APIs & Services > Credentials.
  2. Click on Create credentials > Service account key.
  3. In the Service account drop-down menu, select New Service Account.
  4. Fill in the following information:
  1. Click Create.
  2. Move the downloaded JSON file to the /user-engagement-codelab/start/functions/ directory of your project.
  3. Rename the JSON file to service-account.json.

Enable Firestore

In order to send notifications outside of the conversation, you need a way to store user IDs that can be referenced from your notification code. For this example, we're using a Firestore database to store the user IDs of subscribed users.

Follow these steps to create a Firestore database for your Action:

  1. In the Firebase console, select your Actions project name.
  2. In the left navigation, go to Develop > Database and click Create database.
  3. Select Start in test mode.
  4. Click Enable.

Set up Dialogflow

Follow these steps in the Dialogflow console to create the push notifications opt-in flow:

Prompt the user to subscribe

  1. Set up a new intent to handle the user asking to subscribe to push notifications for cancelled classes. In the Dialogflow console, click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Setup Push Notifications.
  3. Under the Training phrases section, add the following user expressions:
  1. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  2. Click Save at the top of the page.

Handle the user's decision

  1. Set up a new intent to handle the user's response to the push notifications subscription prompt. Click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Confirm Push Notifications.
  3. Under the Events section, add actions_intent_PERMISSION. This Dialogflow event will be triggered by the user finishing the push notifications subscription flow, whether they ended up subscribing or not.
  4. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  5. Click Save at the top of the page.


Handle the push notification

You can link your push notifications to a specific intent, so users who tap on the push notification are deep linked directly to that intent in your Action. In this example, add a new intent for push notifications that provides details about cancelled classes.

Follow these steps to add an intent to be triggered by the user tapping a push notification:

  1. In the Dialogflow console, click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Class Canceled.
  3. Under the Training phrases section, add Cancelations as a user expression.
  4. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  5. Click Save at the top of the page.

Send test notifications mid-conversation

In production, you should have a script separate from your Action fulfillment code that sends push notifications. For this example, create an intent that you can invoke to send a push notification while talking to your Action. This intent is only for debug purposes; in practice, push notifications shouldn't be handled by your fulfillment or otherwise triggered as part of your Action's conversation.

Follow these steps to create an intent for testing push notifications:

  1. For testing and debugging purposes, set up a new intent that allows you to send push notifications to subscribed users. In the Dialogflow console, click the + button next to Intents in the left navigation to create a new intent.
  2. Name this new intent Test Notification.
  3. Under the Training phrases section, add Test notification as a user expression.
  4. Under the Fulfillment section, toggle the Enable webhook call for this intent option.
  5. Click Save at the top of the page.

Turn on push notifications

Follow these steps to enable push notifications for the Class Canceled intent:

  1. In the Dialogflow console, go to Integrations in the navigation bar.
  2. On the Google Assistant card, click Integration Settings.
  3. Add Class Canceled as an Implicit invocation intent. This step is necessary for Dialogflow to recognize that users can start your conversation with the Class Canceled intent (by tapping a push notification).
  4. Click Close.


  1. In the Actions console, go to Build > Actions in the left navigation bar.
  2. Click on Class Canceled under the Actions list.
  3. Under the User engagement section, toggle the Would you like to send push notifications? option.
  4. Set a descriptive Content title that describes the push notification. The context will be "Is it ok if I send push notifications for <content title>?", so make sure your title is both descriptive and sounds correct when spoken aloud. For this example, set the Content title to class cancelations.
  5. Click Save at the top of the page.

Implement the fulfillment

To implement the fulfillment in your webhook, complete the following steps:

Load dependencies

In the index.js file, update the require() function to add the UpdatePermission package from the actions-on-google package, so your imports look like this:

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
  UpdatePermission,
} = require('actions-on-google');

Update suggestion chips

In the index.js file, add a NOTIFICATIONS entry to the list of suggestion chip titles, so your Suggestion definition looks like this:

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
  NOTIFICATIONS: 'Get notifications',
};

Set up new imports

In order to connect to your Firestore database, add the firebase-admin package and add constants for the fields stored in the database. Also, import the google-auth-library and request packages to handle authentication and requests to the Actions API.

In the index.js file, add the following code to your imports:

index.js

// Firebase admin import
const admin = require('firebase-admin');

// Initialize Firestore
admin.initializeApp();
const db = admin.firestore();

// Firestore constants
const FirestoreNames = {
 INTENT: 'intent',
 USER_ID: 'userId',
 USERS: 'users',
};

// Actions API authentication imports
const {auth} = require('google-auth-library');
const request = require('request');

Offer to set up class cancelation notifications

In the index.js file, replace the following code:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

with this:

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like to receive daily reminders of upcoming classes, subscribe to notifications about cancelations, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.NOTIFICATIONS,
Suggestion.HOURS]));
    };
  };
});

Add fulfillment for new intents

When the user says they want to subscribe to push notifications, call the UpdatePermission helper to request permission from the user. If that's successful, the PERMISSION argument will be added to the conv object's arguments which you can check to pivot the conversation.

Once you have the user's permission, take the user ID from the conv object's arguments and save that in your database. You'll later send this user ID to the Actions API, which is how the Assistant will determine who receives the notification.

Lastly, add fulfillment for the Class Canceled intent that's triggered by tapping the push notification. In this example your response is a placeholder string, though in a production-ready version of this Action your notification script would provide more dynamic information about which class has been canceled.

In the index.js file, add the following code:

index.js

// Call the User Information helper for permission to send push notifications
app.intent('Setup Push Notifications', (conv) => {
 conv.ask('Update permission for setting up push notifications');
 conv.ask(new UpdatePermission({intent: 'Class Canceled'}));
});

// Handle opt-in or rejection of push notifications
app.intent('Confirm Push Notifications', (conv) => {
 if (conv.arguments.get('PERMISSION')) {
   let userId = conv.arguments.get('UPDATES_USER_ID');
   if (!userId) {
     userId = conv.request.conversation.conversationId;
   }
   // Add the current conversation ID and the notification's
   // target intent to the Firestore database.
   return db.collection(FirestoreNames.USERS)
   .add({
     [FirestoreNames.INTENT]: 'Class Canceled',
     [FirestoreNames.USER_ID]: userId,
   })
   .then(() => {
     conv.ask(`Great, I'll notify you whenever there's a class cancelation. ` +
     'Can I help you with anything else?');
   });
 } else {
   conv.ask(`Okay, I won't send you notifications about class cancelations. ` +
     'Can I help you with anything else?');
 }
 if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.CLASSES, Suggestion.HOURS]));
  }
});

// Intent triggered by tapping the push notification
app.intent('Class Canceled', (conv) => {
 conv.ask('Classname at classtime has been canceled.');
});

Add test notifications

To send a push notification to a user, send a POST request to the Actions API with the user ID, the notification's title, and the target intent. In this example, triggering the Test Notification intent will iterate through your Firestore database and send push notifications to every user who's subscribed to notifications.

Remember that, in this example, you're including the code that sends the push notification in your webhook fulfillment and triggering that code by invoking a test intent in your conversation. In Actions that you intent to publish, your push notification code should exist in a script separate from your fulfillment.

In the index.js file, add the following code:

index.js

// Debug intent to trigger a test push notification
app.intent('Test Notification', (conv) => {
 // Use the Actions API to send a Google Assistant push notification.
 let client = auth.fromJSON(require('./service-account.json'));
 client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation'];
 let notification = {
   userNotification: {
     title: 'Test Notification from Action Gym',
   },
   target: {},
 };
 client.authorize((err, tokens) => {
   if (err) {
     throw new Error(`Auth error: ${err}`);
   }
   // Iterate through Firestore and send push notifications to every user
   // who's currently opted in to canceled class notifications.
   db.collection(FirestoreNames.USERS)
       .where(FirestoreNames.INTENT, '==', 'Class Canceled')
       .get()
       .then((querySnapshot) => {
         querySnapshot.forEach((user) => {
           notification.target = {
             userId: user.get(FirestoreNames.USER_ID),
             intent: user.get(FirestoreNames.INTENT),
           };
           request.post('https://actions.googleapis.com/v2/conversations:send', {
             'auth': {
               'bearer': tokens.access_token,
             },
             'json': true,
             'body': {'customPushMessage': notification, 'isInSandbox': true},
           }, (err, httpResponse, body) => {
             if (err) {
               throw new Error(`API request error: ${err}`);
             }
             console.log(`${httpResponse.statusCode}: ` +
               `${httpResponse.statusMessage}`);
             console.log(JSON.stringify(body));
           });
         });
       })
       .catch((error) => {
         throw new Error(`Firestore query error: ${error}`);
       });
 });
 conv.ask('A notification has been sent to all subscribed users.');
});

Test your push notifications

In the terminal, run the following command to deploy your updated webhook code to Firebase:

firebase deploy

To test out notifications in the Actions simulator, follow these steps:

  1. In the Actions console, navigate to Test > Simulator.
  2. Type Talk to my test app into the Input field and press enter.
  3. Type Learn about classes and press enter.
  4. Type Get notifications and press enter.
  5. If you haven't already granted your Action permission to send you push notifications, type yes and press enter.
  6. Type yes and press enter. Your Google account should now be subscribed to push notifications for this Action.

  1. Type no and press enter to exit.
  2. Type Talk to my test app and press enter to start a new conversation.
  3. Type Test notification and press enter.

Within a few minutes you should receive a "Test Notification from Action Gym" Assistant push notification on your mobile device. Tapping this notification will deep link you to the Class Canceled intent of your Action.

So far we've discussed engagement features that you can implement to keep users coming back to your Action, but those are predicated on having users who discover and use your Action.

You can create an Action link that will link users on mobile devices directly to your Action on the Google Assistant. Since an Action link is a standard hyperlink, you can add it to a website or any web marketing materials like a blog or social media post.

In this step, you'll learn about what an Action link is, how to create one for your Action's welcome intent, and how to add it to a simple website for testing.

How will this engage users?

Drawing users to your Action for the first time can be challenging, especially when they need explicitly invoke your Action on the Assistant. An Action link alleviates this friction by giving users a direct link to your Action. When a user follows your Action link on an Assistant-enabled device, they're taken directly to your Action. When a user opens your link on a non-mobile device or any other device that doesn't support the Assistant, they'll still be taken to your Actions directory listing (if it's been published) so the link can still market your Action to those users.

Action links can be a useful engagement tool, so you should create one if you're planning on advertising your Action through your website or social media. Just be aware of the following tips before you create and distribute an Action link:

Turn on Action links

Follow these steps to create an Action link for the welcome intent:

  1. In the Actions console, go to Build > Actions in the left navigation bar.
  2. Click on actions.intent.MAIN under the Actions list.
  3. Under the Links section, toggle the Would you like enable a URL for this Action option.
  4. Set a descriptive Link title that describes your Action. Make your title a simple verb-noun pair that describes what the user can accomplish with your Action. For this example, set the Link title to learn about Action Gym.
  5. Copy the HTML snippet from the bottom of this page and save it for later.
  6. Click Save at the top of the page.

Deploy a test website

To test your Action link, you can use Firebase tools to deploy a test website alongside your fulfillment. We've already built a simple test website for this example, you just need to add your Action link.

Go to your fulfillment's /user-engagement-codelab-nodejs/start/public/ directory and open the index.html file in a text editor.

In the index.html file, paste your Action link's HTML snippet into the body element. The file should end up looking like the snippet below:

index.html

<body>
    <p>
     <a href="https://assistant.google.com/services/invoke/uid/000000efb5f2fd97">🅖 Ask my test app to learn about Action Gym
     </a>
    </p>
</body>

Test your Action link

In the terminal, run the following command to deploy your test website to Firebase:

firebase deploy

Once the deploy command finishes running, take note of the Hosting URL in the output.

Go to this URL on your mobile device's web browser and you should see the Action link on your test website. Clicking this link on your mobile device should take you to your Action's welcome intent in the Assistant.

You can also try going to the Hosting URL on a desktop browser, which should take you to a 404 page in the Assistant directory since your Action isn't published.

Congratulations!

You've now learned about the importance of user engagement when developing an Action, what user engagement features are available on the platform, and how to add each feature to an Action.

Additional learning resources

Explore these resources to learn more about user engagement for your Action:

Follow us on Twitter @ActionsOnGoogle to stay tuned to our latest announcements, and tweet to #AoGDevs to share what you have built!

Feedback survey

Before you go, please fill out this form to let us know how we're doing!