1. Overview
Actions on Google is a developer platform that lets you create software to extend the functionality of Google Assistant, Google's virtual personal assistant, across more than 1 billion devices, including smart speakers, phones, cars, TVs, headphones, and more. Users engage Assistant in conversation to get things done, like buying groceries or booking a ride. (For a complete list of what's possible, 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 third-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 to 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 that easier, you can implement several features in your Action that give users paths back into your conversation.
The codelab covers user-engagement features and best practices for Actions on Google.
What you'll build
You'll enhance a feature that's already been built by enabling it to:
- Send users a daily update that they can tap to talk to your Action
- Send users push notifications that link back to your Action
- Create a link that takes users to your Action from a mobile web browser
What you'll learn
- What is user engagement and why it's important for an Action's success
- How to modify an Action to increase user engagement
- Which user engagement features to use in different kinds of Actions
- How to use the Actions API to send notifications through Assistant
What you'll need
You must have the following tools:
- An IDE/text editor of your choice, such as WebStorm, Atom, or Sublime
- A terminal to run shell commands with Node.js, npm, and git installed
- A web browser, such as Google Chrome
- A local development environment with the Firebase command-line interface
- A mobile device (Android or iOS) with Assistant (You must be signed-in to Assistant with the same Google Account that you'll use to build this project.)
Familiarity with JavaScript (ES6) is also strongly recommended, although not required, to understand the webhook code.
2. Set up your project
This section shows you how to add user engagement features to a complete, previously built Action.
Understand the sample
The sample for this codelab is a simple Action for a fictional gym named "Action Gym." The Action provides information about the gym, including a list of classes that rotate each day. An informative Action such as this is a good candidate for all user-engagement features because the rotating class list gives different useful information each day.
The following diagram shows the Action Gym sample's conversational flow:
You'll make minor modifications to the dialog to better suit the engagement features you add. However, 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, complete the following steps:
- Open the Actions console.
- Click New project.
- Type in a Project name, like
engagement-codelab
. - Click Create Project.
- Rather than pick a category, scroll down to the More options section and click the Conversational card.
- Click Build your Action to expand the options and select Add Action(s).
- Click Add Your First Action.
- On the Create Action dialog, select Custom Intent, and then click Build to launch the Dialogflow console.
- In the Dialogflow console's agent creation page, click Create.
- Click the (gear icon) on the left navigation.
- Click Export and Import, then Restore From Zip.
- Upload the
agent.zip
file from the/user-engagement-codelab-nodejs/start/
directory you downloaded earlier. - Type
RESTORE
and click Restore. - 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:
- Open the Firebase Console.
- Select your Actions project from the list of options.
- 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.
- 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:
- Open the Dialogflow console (you can close the Firebase console if you'd like).
- Click Fulfillment on the left navigation.
- Enable Webhook.
- Paste the URL you copied from the Firebase dashboard if it doesn't already appear.
- 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:
- In the Dialogflow console left navigation, click on Integrations > Google Assistant.
- Make sure Auto-preview changes is enabled and click Test to update your Actions project.
- The Actions simulator loads your Actions project. To test your Action, type
Talk to my test app
into the Input field and press enter. - 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.
3. Add daily update subscriptions
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 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:
- Make sure the daily updates will result in the user seeing different, useful information every day. If tapping a daily update results in the same prompt every time, the user will probably unsubscribe after a couple days.
- Make sure your dialog makes sense to your user if they jump straight to your daily update's intent. Your user won't necessarily start from the beginning of the conversation, so they shouldn't be expected to have much context.
- Show your user the benefit of your Action before prompting them to subscribe to daily updates. Your user should be thinking "I want this content every day" when they are given the option to subscribe.
- Don't overwhelm the user with repeated suggestions to subscribe. Offer a daily update subscription right after showing the user what they'd subscribe to, and avoid pestering them about it elsewhere.
- Keep the conversation short after the update intent is triggered. Most daily updates should only consist of a single response then close without requiring user input.
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:
- In the Actions console, click the Develop tab, and choose Actions in the left navigation bar.
- Click on Class List under the Actions list.
- Under the User engagement section, toggle the Would you like to offer daily updates to users option.
- 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
. - 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
- 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.
- Name this new intent
Setup Updates
. - Under the Training phrases section, add the following user expressions:
Send daily reminders
Reminder
Remind me
Updates
Upcoming classes
- Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- Click Save at the top of the page.
Handle the user's decision
- 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.
- Name this new intent
Confirm Updates
. - 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. - Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- 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, Assistant triggers 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:
- In the Actions console, navigate to Test.
- Type
Talk to my test app
into the Input field and press enter. - Type
Learn about classes
and press enter. Your Action's response should now offer to send daily reminders. - Type
Send daily reminders
and press enter. - 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 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 Assistant, giving you a list of upcoming classes:
4. Add push notifications
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 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:
- Actions API account - You send notifications to the user by sending a
POST
request to an API, so you'll need to set up a service account and credentials to interface with this API. - Permission helper - You need the user's permission to access the user ID needed to send them push notifications. In this example, you'll use a client library function to call the permission helper and request this ID.
- Storage - In order to send push notifications to a user outside of a conversation, you need to store user IDs somewhere that can be recalled at-will. In this example, you'll set up a Firestore database to store information for each user.
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 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:
- Plan some example schedules for your push notifications. If you plan on only sending one push notification per day, consider using daily updates instead.
- Make sure your push notifications will provide useful information every time they're received. Your notifications can also deep link to one of your Action's intents, so make sure the intent is useful and relevant.
- Be explicit when asking a user to subscribe to push notifications. They should understand what to expect with each push notification, and have some idea of how often the notifications are sent.
Enable the Actions API
- Open the Google Cloud console and select your Actions project name in the dropdown.
- In the navigation menu (☰), go to APIs & Services > Library.
- 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:
- In the Google Cloud Console's navigation menu (☰), go to APIs & Services > Credentials.
- Click on Create credentials > Service account key.
- In the Service account drop-down menu, select New Service Account.
- Fill in the following information:
- Service account name:
service-account
- Role: Project > Owner
- Service account ID:
service-account
(always followed by @<project_id>.iam.gserviceaccount.com) - Key type: JSON
- Click Create.
- Move the downloaded JSON file to the /user-engagement-codelab/start/functions/ directory of your project.
- 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:
- In the Firebase console, select your Actions project name.
- In the left navigation, go to Develop > Database and click Create database.
- Select Start in test mode.
- 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
- 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.
- Name this new intent
Setup Push Notifications
. - Under the Training phrases section, add the following user expressions:
Subscribe to notifications
Send notification
Notify me
Send class notifications
Cancelled notifications
- Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- Click Save at the top of the page.
Handle the user's decision
- 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.
- Name this new intent
Confirm Push Notifications
. - 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. - Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- 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:
- In the Dialogflow console, click the + button next to Intents in the left navigation to create a new intent.
- Name this new intent
Class Canceled
. - Under the Training phrases section, add
Cancelations
as a user expression. - Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- 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:
- 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.
- Name this new intent
Test Notification
. - Under the Training phrases section, add
Test notification
as a user expression. - Under the Fulfillment section, toggle the Enable webhook call for this intent option.
- Click Save at the top of the page.
Turn on push notifications
Follow these steps to enable push notifications for the Class Canceled intent:
- In the Dialogflow console, go to Integrations in the navigation bar.
- On the Google Assistant card, click Integration Settings.
- 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).
- Click Close.
- In the Actions console, click the Develop tab, and choose Actions in the left navigation bar.
- Click on Class Canceled under the Actions list.
- Under the User engagement section, toggle the Would you like to send push notifications? option.
- 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
. - 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 Assistant determines 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:
- In the Actions console, go to the Test tab.
- Type
Talk to my test app
into the Input field and press enter. - Type
Learn about classes
and press enter. - Type
Get notifications
and press enter. - If you haven't already granted your Action permission to send you push notifications, type
yes
and press enter. - Type
yes
and press enter. Your Google account should now be subscribed to push notifications for this Action.
- Type
no
and press enter to exit. - Type
Talk to my test app
and press enter to start a new conversation. - 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.
5. Create an Assistant link
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 Assistant link that will link users on mobile devices directly to your Action on Assistant. Since an Assistant 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 Assistant 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 to explicitly invoke your Action on Assistant. An Assistant link alleviates this friction by giving users a direct link to your Action. When a user follows your Assistant 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 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.
Assistant 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 Assistant link:
- Assistant links only work once your Action is published. While your project is in a draft state, the link will only work on your own devices. Anyone else will be taken to a 404 page in the Actions directory.
- You can let users test an Assistant link prior to publishing by releasing your Action in an alpha or beta environment. Note that only users who participate in your alpha or beta will be able to test your Assistant link.
- Make sure the destination intent for your Assistant link makes a good first impression with new users. Your welcome intent is the default destination for an Assistant link because it should already do a good job of introducing your Action
Turn on Assistant links
Follow these steps to create an Assistant link for the welcome intent:
- In the Actions console, click the Develop tab, and chooseActions in the left navigation bar.
- Click on actions.intent.MAIN under the Actions list.
- Under the Links section, toggle the Would you like enable a URL for this Action option.
- 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
. - Copy the HTML snippet from the bottom of this page and save it for later.
- Click Save at the top of the page.
Deploy a test website
To test your Assistant 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 Assistant 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 Assistant 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 Assistant 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 Assistant link on your test website. Clicking this link on your mobile device should take you to your Action's welcome intent in 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.
6. Next steps
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:
- User engagement & Assistant links docs: The official Actions on Google documentation on the features discussed in this codelab and user engagement in general.
- User retention analytics: Documentation for the analytics feature in the Actions console that shows user retention for your published Action.
- Conversational design guidelines: Best practices and guidelines for how to design user engagement features.
- Actions on Google GitHub repo: Sample code and libraries.
- r/GoogleAssistantDev: The official Reddit community for developers working with Assistant.
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!