Google Assistant Webserver in a Docker container

googleassistant
docker
Tags: #<Tag:0x00007f1b97091438> #<Tag:0x00007f1b97091168>

#1

Google Assistant Webserver in a Docker container

What is this?

This is a emulated Google Assistant with a webserver attached to take commands over HTTP packaged in a Docker container. The container consists of the Google Assistant SDK, python scripts that provide the Flask REST API / OAuth authentication and modifications that base it from the Google Assistant library.

I did not write this code, I simply pulled pieces and modified them to work together. AndBobsYourUncle wrote Google Assistant webserver Hassio add-on which this is largely based on. Chocomega provided the modifications that based it off the Google Assistant libraries.

How does this differ from AndBobsYourUncle’s Google Assistant Webserver? This project is modified, running based on the Google Assistant libraries not the Google Assistant Service which allows for additional functionality such as remote media casting (Casting Spotify) See the table here. However this method requires a mic and speaker audio device on the host machine.

Setup

  1. Go the Configure a Developer Project and Account Settings page of the Embed the Google Assistant procedure in the Library docs.

  2. Follow the steps through to Register the Device Model and take note of the project id and the device model id.

  3. Download OAuth 2.0 Credentials file, rename it to client_secret.json and move it to the configuration directory /home/user/docker/config/gawebserver.

  4. In a Docker configuration below, fill out the DEVICE_MODEL_ID and PROJECT_ID environment variables with the values from previous steps. Lastly change the volume to mount your configuration directory to /config.

First Run

  • Start the container using Docker Run or Docker Compose. It will start listening on ports 9324 and 5000. Browse to the container on port 9324 (http://containerip:9324) where you will see Get token from google: Authentication.
  • Follow the URL, authenticate with Google, return the string from Google to the container web page and click connect. The page will error out and that is normal, the container is now up and running.

Docker Run

$ docker run -d --name=gawebserver \
    --restart on-failure \
    -v /home/user/docker/config/gawebserver:/config \
    -p 9324:9324 \
    -p 5000:5000 \
    -e CLIENT_SECRET=client_secret.json \
    -e DEVICE_MODEL_ID=device_model_id \
    -e PROJECT_ID=project_id \
    --device /dev/snd:/dev/snd:rwm \
    robwolff3/ga-webserver

Docker Compose

version: "3.4"
services:
  gawebserver:
    container_name: gawebserver
    image: robwolff3/ga-webserver
    restart: on-failure
    volumes:
      - /home/user/docker/config/gawebserver:/config
    ports:
      - 9324:9324
      - 5000:5000
    environment:
      - CLIENT_SECRET=client_secret.json
      - DEVICE_MODEL_ID=device_model_id
      - PROJECT_ID=project_id
    devices:
      - "/dev/snd:/dev/snd:rwm"

Test it

  • Test out your newly created ga-webserver by sending it a command through your web browser.
  • Send a command http://containerip:5000/command?message=Play Careless Whisper by George Michael on Kitchen Stereo
  • Broadcast a message http://containerip:5000/broadcast_message?message=Alexa order 500 pool noodles

Not sure why a command isn’t working? See what happened in your Google Account Activity or under My Activity in the Google Assistant App.

Home Assistant

Here is an example how I use the ga-webserver in Home Assistant to broadcast over my Google Assistants when my dishwasher has finished.

configuration.yaml

notify:
  - name: ga_broadcast
    platform: rest
    resource: http://containerip:5000/broadcast_message
  - name: ga_command
    platform: rest
    resource: http://containerip:5000/command

automations.yaml

  - alias: Broadcast the dishwasher has finished
    initial_state: True
    trigger:
      - platform: state
        entity_id: input_select.dishwasher_status
        to: 'Off'
    action:
      - service: notify.ga_broadcast
        data:
          message: "The Dishwasher has finished."

My Home Assistant Configuration repository.

Troubleshooting

  • Broadcast messages not working? You may need to set an address on the ga-webserver the same as the address’s registered with your other Google Assistant devices. In the Google Assistant app go to More > Settings > Settings > Assistant. At the bottom select your ga-webserver and set the applicable address.

  • If it was working and then all the sudden stopped then you may need to re-authenticate. Stop the container, delete the access_token.json file from the configuration directory, repeat the First Run procedure above.

  • Have problems? Check the container logs: docker logs -f gawebserver


Community Hass.io Add-on: Google Assistant Webserver (broadcast messages without interrupting music)
#2

Awesome ! I’m glad to see your work will make this service more accessible. :beers:


#3

How do you use this without a speaker? I got it authorized, but it quits because it can’t initialize a speaker.

Running Ubuntu 16.04 with Docker on a NUC.

googleassistant is the name of the docker container in my docker compose file BTW.

googleassistant    | ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
googleassistant    | ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
googleassistant    | ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
googleassistant    | ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
googleassistant    | ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
googleassistant    | [FATAL:audio_input_stream.cc(47)] Input device could not be opened: default
googleassistant exited with code 139

Here is the docker compose configuration (sanitized):

  googleassistant:
    container_name: googleassistant
    image: robwolff3/ga-webserver
    restart: unless-stopped
    volumes:
      - /srv/docker/googleassistant:/config
    ports:
      - 9324:9324
      - 5000:5000
    environment:
      - CLIENT_SECRET=client_secret.json
      - DEVICE_MODEL_ID=id
      - PROJECT_ID=id
    devices:
      - "/dev/snd:/dev/snd:rwm"  #I tried not including this but it still fails.

#4

That’s a good question. Personally I am running Docker in Debian on an old desktop computer that has audio inputs and outputs integrated on motherboard. I did not have to configure anything, the defaults Docker used on the container must have just worked.

I was running the Google Assistant Library on a Raspberry Pi before and used Google’s documentation that goes over configuring and setting the mic and speaker device defaults. Figured out that I had to use a SYBA USB Sound Adapter and a USB mic to get it working on the Pi because it has none on the board itself. With those plugged in and the default audio devices recognized by the OS it started working.

Not sure that it’ll work without speaker and mic devices on the host OS.

https://developers.google.com/assistant/sdk/guides/library/python/embed/audio?hardware=ubuntu


#5

Great thing! Really cool to get more functions!

Hope anyone finds a way to run it without mic and speaker to get it running on a Pi!


#6

Good job !!


#7

Double check your PROJECT_ID is set correctly

google.assistant.library.device_helpers.RegistrationError: Failed to register device INVALID_ARGUMENT (400): Could not get the device instance. Project_id from side channel and project_id from url do not match.


#8

USB sound cards are pretty cheap (~7$ on amazon or maybe even less on aliexpress), I don’t know about the compatibility but it might worth a try.
The SYBA model seems to work fine on the Raspberry Pi for @robwolff3 (is it this one ? https://www.amazon.com/external-Adapter-Windows-Microphone-SD-CM-UAUD/dp/B001MSS6CS)

I do agree that a way to run it without audio input/output would be great though as we don’t specifically use it.

On a side note, the Google assistant Library version 1.0.1 has now limited support for ARMv6 architecture (Raspberry Pi Zero). Which means a new cheap platform to try this on !


#9

Replying to myself :sweat_smile:, with deeper thoughts (well not that deep) I think it should be possible to create a dummy sound card device on linux…


#10

If anyone knows how to do this, could be very beneficial to the project.


#11

Sometimes I’ve got thir error :
UnicodeEncodeError: ‘ascii’ codec can’t encode character ‘\xe9’ in position 42: ordinal not in range(128) stderr
On a Synology nas. Any idea?

How to say to play music with a timer? Thanks !

commands work, but broadcasting no. It was working fine with andbobsyouruncle-amd64-google-assistant-webserver. Is it playing only on soundcard?


#12

\xe9 is a small letter E with an acute accent mark. Try replacing it with a regular e.


#13

Yes I know, I’m french and this characters are regularly employed. I don’t undersand why it does’nt work, while it work with andbobsyouruncle on the same platform.

Thanks for your help.


#14

You’re definitely right.
Sorry for the noob question: I’m very new to home assistant and am using Hass.io. I only installed new things using the hassio plugins.

Can I install this in hassio? If yes: will it discover the USB soundcard?


#15

@capstan1 This project is not made to work with Hass.io. Personally I use Docker so this was easy to just share with others to use. The only solution for Hass.io right now is AndBobsYourUncle’s however it cannot cast remote media (spotify). Anyone is welcome to take what I / we’ve done and make it an add-in for Hass.io.


#16

I don’t need streaming necessarily (would be a great addition to have though). My problem with the hassio plugin is only that broadcasting isn’t working for me, so I wanted to try your solution.


#17

For me it works without real soundcard enabled, using:
sudo modprobe snd-dummy

I’m able to use it and play music on selected device. Many thanks for great work.