Skip to content

Google Assistant

Botsquad bots can also be used to run voice actions on the Google Assistant.


To use Google Assistant with a bot, you need to go through a few steps.

  1. Enable the Google Assistant channel for your bot by going to Settings → Connect → Google Assistant and click "Connect to Google Assistant".

  2. Create a project on Actions on Google. Choose your language and country and in the next screen, do not set up a pre-defined agent but choose 'skip'.

  3. Install the gactions command-line utility on your computer, by visiting this page.

  4. In the botsquad studio, follow the instructions for the terminal commands that you have to execute.

Once this is all set up, you can now in the Google Actions console try your action in the simulator and see it interact with your code on Botsquad.

Optional: Account linking

If you want to enable account linking for your action, you need to enter your Account Linking client ID in the Google Assistant connections page in the studio.

You can find your client ID in the account linking section of the Actions console. Note that you will also need to re-submit your action, enter the terms & conditions URL and provide testing instructions for Google

Bubblescript integration

Detecting the client capabilities

To check whether we are running under Google assistant, we simply check user.frontend:

if user.frontend == "google_assistant" do
  say "Hello from Google!"

Furthermore, to check whether we are running an assistant with a screen output, you could do something like this:

has_screen = contains(pluck(google_assistant.surface.capabilities, "name"), "actions.capability.SCREEN_OUTPUT")
if has_screen do
  say "Let me show you this image..."
  show image "http://..."
  say "To show the image, please run me on a device with a screen."

As shown here, when your bot runs through Google Assistant, some extra information is exposed in the bot script, under the google_assistant key:

  "availableSurfaces" => [
      "capabilities" => [
        %{"name" => "actions.capability.AUDIO_OUTPUT"},
        %{"name" => "actions.capability.SCREEN_OUTPUT"},
        %{"name" => "actions.capability.WEB_BROWSER"}
  "isInSandbox" => true,
  "requestType" => "SIMULATOR",
  "surface" => %{
    "capabilities" => [
      %{"name" => "actions.capability.SCREEN_OUTPUT"},
      %{"name" => "actions.capability.ACCOUNT_LINKING"},
      %{"name" => "actions.capability.AUDIO_OUTPUT"},
      %{"name" => "actions.capability.MEDIA_RESPONSE_AUDIO"},
      %{"name" => "actions.capability.WEB_BROWSER"}

See Google's documentation on the AppRequest info for more information about these fields.

The user, conversation and inputs fields of AppRequest are not mapped in the Bubblescript context, these are handled by the platform internally.

Account linking in Bubblescript

Once account linking is set up, you can trigger it by sending a special google_assistant_intent input method.

For example, the following code for a google action will check whether you have linked your account, and if not, first ask you to do so. After you approve with Google that you want to link your account, the conversation continues in the script where it left, saying "Thanks for creating the account". At that point, all user information (user name, email address) is available.

When a new conversation is started, it will continue in the second main dialog, which says "Welcome back".

dialog main when !user.first_name do
  say "You have to create an account first in order to use this action."

  await input_method("google_assistant_intent", intent: "actions.intent.SIGN_IN")

  if user.first_name do
    # account linking successful
    say "Hi #{user.first_name}, thanks for creating the account!"
    # user cancelled
    say "Okay, no problem!"

dialog main when user.first_name do
  say "Hi #{user.first_name}, good that you are back."

Note that this is a simplified example, the Google Actions guidelines specify that you will have to provide a good UX for the case where anonymous users use your action, triggering account linking as the first thing in your action will most likely get it rejected.

Conversational exits

Some intents are triggered by google automatically on special occasions. One of these is the Conversational Exit; for instance the word "stop"; a user can say this any time and your action will be stopped. However, you have still room to say one more thing, for instance to say a custom goodbye message. You can do this by implementing the "$stop" event:

dialog event: "$stop" do
  say "Alright, see you next time."


Another in-dialog intent that the Google Assistant can send is a Reprompt; when the speaker does not understand the user fully, a $no_input event is sent to the conversation, which can then be responded on, to ask the user to repeat the question.

The $no_input event has a payload with two fields:

  • event.payload.is_final_reprompt - whether the Assistant is giving up and closing the conversation.
  • event.payload.reprompt_count - how many times before a reprompt has been sent. At max 3 reprompts will be sent. When reprompt_count == 2, it is the final reprompt.

An example of a reprompt interaction would be the following:

dialog event: "$no_input" when event.payload.is_final_reprompt do
  say "Sorry, I'm giving up, goodbye"

dialog event: "$no_input" do
  once do
    say "Can you repeat that?"
    say "I still don't get it."

The $no_input reprompt only works on Google Home speaker devices, not on mobile phones.

if the $stop or $no_input event is not caught by your bot, please re-link your bot to Google Actions again, by downloading the actions JSON file and runing the gactions command again.

"Deep linking" into your action - the trigger query

It is possible to start your Google Assistant action by saying something like: "Ok Google, talk to my action about the weather". In this case, your action is invoked with the main dialog, but the variable query.trigger is filled with the part of the prompt after about, in this case, it will contain "the weather".

dialog main when query.trigger do
  say "Welcome to your action."

  # dispatch the query internally to the intent matcher
  invoke message: query.trigger

dialog trigger: "weather" do
  say "So you want to talk about the weather..."