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
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:
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):
. ├── app │ ├── build.gradle │ └── src │ └── main │ ├── java │ ├── resources │ └── webapp ├── build.gradle ├── gradle └── settings.gradle
When it’s done, run
$ gactions init from
/app directory. It should create example config file:
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”
and others. List of queries is defined in actions.json. Here is final configuration for our agent:
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/).
Our app requires a couple dependencies defined in
- 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:
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
- Intents mapped to proper request handlers:
All dependencies for Assistant Actions can be found in AssistantModuleclass.
Final servlet code should be similar to this:
Line 15 is the place where all magic happens:
- POST request comes from Google Assistant. It is parsed to
RootRequestobject (lines: 18–20) and passed to
- Based on defined intents map,
- Picked request handler generates tell response:
- Response is passed to
AppEngineResponseHandlerwhich sends it back to Google Assistant.
At the end you need to add App Engine servlet configuration to your project (files: web.xml and appengine-web.xml):
. ├── app └── src └── main ├── java ... └── webapp └── WEB-INF ├── appengine-web.xml └── 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
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:
$ gactions preview -action_package=app/action.json -invocation_name=Githubcalled from project’s root directory.
- 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! 😊
Final source code of described project can be found on Github.