Hello world Google Home

Github Actions — building first agent for Google Assistant in Java

Some time ago I published unofficial Google Actions SDK written in Java. Source code and documentation can be found on Github: Google-Actions-Java-SDK. Library can be also downloaded from Bintray jCenter:

The goal for this project is to give Android/Java developers possibility to build solutions for Google Home without learning new language (official Actions SDK is written in Node.js).

Google Assistant Action from scratch

In this post we’ll go through Google Assistant agent implementation. We’ll build simple Github client which will tell us what is the one of the hottest repositories from last days.

Source code for final project can be found here: Github Google Actions

Environment configuration

Our Github Actions agent will be built in Java and hosted on App Engine.
At the beginning we need to create new project in Google Cloud Platform dashboard.
When it’s done remember your project ID, it will be needed during configuration. In example described in this post id is: *githubactions*.

Then we need to install CLIs for Google Cloud and Google Actions:

Project init

Now let’s create our Java/gradle project (I use IntelliJ IDEA, free community edition). For better code structure, I also created module app. Final structure looks like this (some files/tries aren’t show for better readability):

When it’s done, run $ gactions init from /app directory. It should create example config file: app/actions.json:

This config file defines our agent’s Actions. It’s mostly self-describing but in case you would like to know better what is happening here, please visit official documentation.

Now let’s update it with our configuration. We would like to have an agent which is able to handle two actions/intents:

  • assistant.intent.action.MAIN (defined in Google Actions SDK)
    Action is launched when user starts talking, but without clear intention e.g.: “Ok Google, talk to Github”. In most cases this should be used as an agent introduction.

  • com.frogermcs.githubactions.intent.TRENDING (defined by us)
    In response to this request, our agent will find one of the hottest repositories from last days. There are a couple utterances which should fire this intent:
    “Ok Google, ask Github what are the hottest repositories”
    “…trending repositories”
    “…hot projects”

    and others. List of queries is defined in actions.json. Here is final configuration for our agent:

###The code

Now let’s build service to handle requests from Google Assistant. We will build simple REST server, which handles POST requests (based on configuration above, both intent requests will be sent to https://githubactions.appspot.com/).

Project configuration

Our app requires a couple dependencies defined in app/build.gradle file:

  • App Engine SDK

  • Google Actions Java SDK (my unofficial library)

  • Google HTTP Client Library for Java — to make calls to Github API. Not a good news for Android devs familiar with Okhttp and Retrofit — because of App Engine restrictions in threading, it’s really hard to make it working here.

  • Dagger 2 — Dependency injection framework to make our code a bit cleaner and easy to extend.

Final gradle files (able to build, run and deploy our GAE code) can be found here:

Servlet

Now let’s build code for processing requests from Google Assistant. At this level, it’s nothing more than just proper configuration of Google Actions Java SDK:

  • Build response handler. This object will be used to pass final responses to Google Assistant. Nothing really interesting, it just meets communication requirements (headers, format) Final code: AppEngineResponseHandler.

  • Build request handlers. Those are responsible for handling particular requests (our MAIN and TRENDING intents). Request handlers should process incoming request and generate tell/ask/permission response. In our app we’ll have only tell responses: greeting (MAIN) and randomly picked hot repository (TRENDING). In the future we’ll build more complex solutions on top of ask and permission responses. Final code for MainRequestHandler and TrendingRequestHandler (take a look at returned variable from getResponse() methods — in both cases we use ResponseBuilder.tellResponse(…).

  • Intents mapped to proper request handlers:

All dependencies for Assistant Actions can be found in AssistantModule class.

Final servlet code should be similar to this:

Line 15 is the place where all magic happens:

1) POST request comes from Google Assistant. It is parsed to RootRequest object (lines: 18–20) and passed to assistantActions.

2) Based on defined intents map, assistantAction passes RootRequest object to MainRequestHandler or TrendingRequestHandler.

3) Picked request handler generates tell response: RootResponse.

4) Response is passed to AppEngineResponseHandler which sends it back to Google Assistant.

Servlet Configuration

At the end you need to add App Engine servlet configuration to your project (files: web.xml and appengine-web.xml):

Their content should be self-explaining:

Now our app is ready to deploy. If the configuration is correct, all you have to do is:

$ ./gradlew app:appengineDeploy

Testing Assistant Actions

Web Simulator

Even if you don’t have Google Home device, it’s still possible to simulate you newly created Assistant Actions. To do this you can use Google Home Web Simulator. All you need to do is:

1) $ gactions preview -action_package=app/action.json -invocation_name=Github called from project’s root directory.

2) Sign-in and start: Web Simulator

More details can be found in official guide.

And that’s all! We’ve just built our very first preview version of Actions for Google Assistant. In future publications we’ll see how to extend its functionality.

Thanks for reading! 😊

Source code

Final source code of described project can be found on Github.

Author

Miroslaw Stanek
Head of Mobile Development @ Azimo Money Transfer

If you liked this post, you can share it with your followers or follow me on Twitter!

Written on May 12, 2017