How to create a Google Action for Google Assistant (Home)
Tags: google, assistant, action, guide
Published: 2022-03-02 20:47:41

Hey, people!

A few weeks ago, I've created an Alexa Skill that provides information about an VR MMORPG called Zenith.  

{% github https://github.com/Markkop/essence-helper-alexa-skill no-readme %}

The problem I was trying to solve with this skill is finding out more about the game without the need to remove the headset while playing.  

People on [Reddit](https://www.reddit.com/r/ZenithMMO/comments/t0bnis/ive_made_an_alexa_skill_that_provides_information/) liked it and suggested creating the same skill but for Google Assistant.  

I had no idea how to make one, so I've taken this opportunity to challenge myself and also share my learnings in a blog post.
So shall we?

## Setting Up

[This Quick Start](https://developers.google.com/assistant/conversational/quickstart) guide is pretty much what you need to get everything ready for development.  
However, here are some of the troubles I had and the solutions I've found:

- If you try to install the `gactions` CLI using the zipped file, you might get the ["This app is blocked"](https://stackoverflow.com/questions/70321984/this-app-is-blocked-message-when-using-gactions-cli) screen. Instead, you can install it using the `npm` package, which is even easier:  
```
npm i -g @assistant/gactions
```

- You'll need to enable both Cloud Functions and Cloud Build API. It took me a while to notice that the error returned from the `gactions deploy view` was different after enabling Cloud Function API.
```json
[ERROR] Server did not return HTTP 200.
{
  "error": {
    "code": 403,
    "message": "Asset 'webhooks/ActionsOnGoogleFulfillment' cannot be deployed. [Cloud Functions API has not been used in project 402567933069 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudfunctions.googleapis.com/overview?project=402567933069 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.]"
  }

[ERROR] Server did not return HTTP 200.
{
  "error": {
    "code": 403,
    "message": "Asset 'webhooks/ActionsOnGoogleFulfillment' cannot be deployed. [Build failed: Cloud Build API has not been used in project 402567933069 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=402567933069 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.]"
  }
}
```

- Also, make sure to enable Cloud APIs in the correct project. A new cloud project with the same `projectId` you've set in settings.yaml should be created in the Cloud Dashboard.

![cloud project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p89vr1bgacu9mjtnmoqo.png)

## Using a local editor

If you followed the quick start guide mentioned above, you now have an **Interactive canvas sample** project in your computer.

{% github https://github.com/actions-on-google/actions-builder-canvas-nodejs no-readme %}

Whenever you run `gactions push` inside the `sdk` folder, the project in the [Actions Console](https://console.actions.google.com/) will be updated as well.
You can also pull changes made in the console to the project by running `gactions pull`.
To read more about `gactions` CLI, take a look [here](https://developers.google.com/assistant/actionssdk/gactions).

Remember that you have to `gactions deploy preview` to be able to test your changes in the testing page.

To develop your action, you'll probably be going back and forth between the Web Action Build and the code locally itself. You sure can stick with only one, but sometimes you'll want to visualize and edit the app's flow in the actions console, and other times you'll rather just code a lot using your favorite editor.

## Creating the action

The way Google Actions work is having scenes that trigger intents which call a webhook handler.
The [documentation](https://developers.google.com/assistant/conversational/overview) can give you the details, but the most important point here is that you'll need to add some `app.handlers` into the webhook code and set them on your scenes.

![scene example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73deodw8xe9h4tttho95.png)
 
I won't go further in the explanation on how to use [@assistant/conversation](https://actions-on-google.github.io/assistant-conversation-nodejs/3.7.0/index.html) or how to connect scenes, intents and slots. But I'm sure you can figure them out by trial-and-error and taking a look on [samples](https://developers.google.com/assistant/conversational/samples).

## Testing with preview deployment

At this point, you surely are familiar with the testing console. However, you might want to add [automated tests](https://developers.google.com/assistant/conversational/testing?utm_source=console_simulator&utm_medium=console&utm_campaign=promo_2021_02&utm_term=actions_sdk_testing_library#automated_testing) in your project, so you don't need to do the manual work every time.  

The process is pretty simple, just follow [this project](https://github.com/actions-on-google/actions-builder-conversation-components-nodejs)'s readme instructions and check its sample code.

{% github https://github.com/actions-on-google/actions-builder-conversation-components-nodejs %}

The only problem I had was some weird error with draft deployment. I can't tell for sure, but after deploying a new preview version, the automated tests were not updating with the new code. I believe it was some kind of Google Cloud Function reference error.

The solution was going to the Web Testing page and triggering and new function deployment. 

Having to do this every time is bothersome, but luckily the next step solved this problem as well.

## Testing locally

In order to be able to write some code and test it without the need to deploy it again, I've followed this [guide](https://www.freecodecamp.org/news/how-to-implement-local-fulfillment-for-google-assistant-actions-using-dialogflow-1b3b3a13075f/) and adapted it to Google Conversation.

The only thing is that we now have to use an HTTPS Endpoint for fulfillment method instead of the Inline Cloud Functions.

![fulfillment method selection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhi5tqhm6zu0uo7om0vo.png)

The endpoint we're going to use is actually the same Firebase Function we've been using. You can grab it from [Firebase Console](https://console.firebase.google.com), it's the one with **ActionsOnGoogleFulfillment** in its URL.  

However, we're only using this endpoint when our skill is ready for production. While testing and developing, we will set its endpoint to the **Ngrok Public URL** as described in the guide linked above.

In fact, the tips and tricks on how I've set this up is content for another post. For now you can check how I'm using it in my github repository:

{% github https://github.com/Markkop/essence-helper-google-action/ no-readme %}

## Releasing

There is no mystery here, just go to the "Deploy" tab, submit your information and create a new release.
After Google's verification, you might have the action officially live!

## Conclusion

I've spent a good amount of time figuring out how to develop a Google Action, specially about some of the resources I've got used to while using Alexa Skills Kit, such as testing with [dialog replay](https://developer.amazon.com/en-US/docs/alexa/smapi/ask-cli-command-reference.html#dialog-command) files and [local development](https://developer.amazon.com/en-US/docs/alexa/smapi/ask-cli-command-reference.html#run-command).  
Certainly, there are pros and cons for each home assistant service, but my next goal is using a framework to develop both at the same time.
Stay tuned!

By the way, if you want to check out my skill live, just say to your Google Home Assistant: "Ok Google, Talk to [Essence Helper](https://assistant.google.com/services/a/uid/0000005dbaeb2c8d?hl=en-US)" 😉