Giter Site home page Giter Site logo

google-assistant-webserver's Introduction

This repository is no longer matained. Use at your own risk.


Google Assistant Webserver in a Docker container

March 25th 2020 - Update

I had issues with my project and starting fresh seemed to fix it.

  • Pull the new container image version
  • Recreate the Google Actions Project following googles new documentation https://developers.google.com/assistant/sdk/guides/service/python
  • Once setup, authenticated and showing up in Google Assistant settings on my phone I had to join the new device to my home in the Google Home app. Then it picked up on my Device Address for broadcasts.

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 or an emulated dummy on the host machine.

Interested in Docker but never used it before? Checkout my blog post: Docker In Your HomeLab - Getting Started.

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, create a configuration directory /home/$USER/docker/config/gawebserver/config and move the file there.
  4. Create an additional folder /home/$USER/docker/config/gawebserver/assistant the Google Assistant SDK will cache files here that need to persist through container recreation.
  5. 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 config and assistant directories to /config and /root/.config/google-assistant-library/assistant

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.
  • To get broadcast messages working an address needs to be set, the same as your other broadcast devices. In the Google Home app go to Account > Settings > Assistant. At the bottom select your ga-webserver and set the applicable address. There you can also set the default audio and video casting devices.

Docker Run

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

Docker Compose

version: "3.7"
services:
  gawebserver:
    container_name: gawebserver
    image: robwolff3/ga-webserver
    restart: on-failure
    volumes:
      - /home/$USER/docker/config/gawebserver/config:/config
      - /home/$USER/docker/config/gawebserver/assistant:/root/.config/google-assistant-library/assistant
    ports:
      - 9324:9324
      - 5000:5000
    environment:
      - CLIENT_SECRET=client_secret.json
      - DEVICE_MODEL_ID=device_model_id
      - PROJECT_ID=project_id
      - PYTHONIOENCODING=utf-8
    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 Home 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.

Known Issues and Troubleshooting

  • There are duplicate devices in the Google Home app - This happens every time the container is recreated, it looses its device_id stored in the container. This is fixed with my add step 4 under Setup. Once the container stores its new device_id there it will persist through container recreation.
  • Error: UnicodeEncodeError: 'ascii' codec can't encode character - zewelor discovered this issue of a Wrong UTF8 encoding setting in the locale env. He solved this by adding the environment variable PYTHONIOENCODING=utf-8 to the Docker configuration.
  • 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.
  • Having other problems? Check the container logs: docker logs -f gawebserver

google-assistant-webserver's People

Contributors

robwolff3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

google-assistant-webserver's Issues

getting encoding error KOREAN

Hello,
I'm getting encoding error:
i use Language KOREAN and test JAPANESE language too.
i try -e PYTHONIOENCODING=utf-8 and euc-kr , but can't work it.
can you fix it?

192.168.0.200 - - [28/May/2019 15:35:07] "GET /command?message=turn%20off%20light HTTP/1.1" 200 -,
[2019-05-28 15:35:18,202] ERROR in app: Exception on /command [GET],
Traceback (most recent call last):,
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1832, in full_dispatch_request,
rv = self.dispatch_request(),
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1818, in dispatch_request,
return self.view_functionsrule.endpoint,
File "/usr/local/lib/python3.5/dist-packages/flask_restful/init.py", line 458, in wrapper,
resp = resource(*args, **kwargs),
File "/usr/local/lib/python3.5/dist-packages/flask/views.py", line 88, in view,
return self.dispatch_request(*args, **kwargs),
File "/usr/local/lib/python3.5/dist-packages/flask_restful/init.py", line 573, in dispatch_request,
resp = meth(*args, **kwargs),
File "/gawebserver.py", line 169, in get,
assistant.send_text_query(message),
File "/usr/local/lib/python3.5/dist-packages/google/assistant/library/assistant.py", line 215, in send_text_query,
self._lib.assistant_send_text_query(self._inst, query.encode('ASCII')),
UnicodeEncodeError: 'ascii' codec can't encode character '\ubd88' in position 0: ordinal not in range(128),
192.168.0.200 - - [28/May/2019 15:35:18] "GET /command?message=불%20꺼 HTTP/1.1" 500 -,

Thank you

I just wanted to thank you for this. I inadvertently revoked access to it yesterday and went to get it set back up, only to realize I have had it running for three years now, and it has just run without problems. An amazing piece of software that I don't know what I would do without. Thanks again.

500 Internal Server Error => it is normal

500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/cherrypy/_cprequest.py", line 628, in respond
    self._do_respond(path_info)
  File "/usr/local/lib/python3.5/dist-packages/cherrypy/_cprequest.py", line 687, in _do_respond
    response.body = self.handler()
  File "/usr/local/lib/python3.5/dist-packages/cherrypy/lib/encoding.py", line 219, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/cherrypy/_cpdispatch.py", line 54, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "/oauth.py", line 46, in token
    self.oauth2.fetch_token(self.user_data['token_uri'], client_secret=self.user_data['client_secret'], code=token)
  File "/usr/local/lib/python3.5/dist-packages/requests_oauthlib/oauth2_session.py", line 307, in fetch_token
    self._client.parse_request_body_response(r.text, scope=self.scope)
  File "/usr/local/lib/python3.5/dist-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 415, in parse_request_body_response
    self.token = parse_token_response(body, scope=scope)
  File "/usr/local/lib/python3.5/dist-packages/oauthlib/oauth2/rfc6749/parameters.py", line 425, in parse_token_response
    validate_token_parameters(params)
  File "/usr/local/lib/python3.5/dist-packages/oauthlib/oauth2/rfc6749/parameters.py", line 432, in validate_token_parameters
    raise_from_error(params.get('error'), params)
  File "/usr/local/lib/python3.5/dist-packages/oauthlib/oauth2/rfc6749/errors.py", line 405, in raise_from_error
    raise cls(**kwargs)
oauthlib.oauth2.rfc6749.errors.InvalidGrantError: (invalid_grant) Bad Request
Powered by CherryPy 18.1.0

RaspberryPi4

Does this not work with a Pi4? Unfortunately I get an exec error in my logs :-/

Trouble access docker image command line.

I am having some problems with my audio. I am running it on a synology NAS (DS918+) So I thought, see if I can access the image through the command line so I would have a shell to troubleshoot the audio.
However docker run -it robwolff3/ga-webserver /bin/sh results in an error [Error] You need initialize GoogleAssistant with a client secret json!

BTW not relevant to this issue, but log when starting normally is it seems it can't find the soundcard.:

2019-06-02 08:32:57,stderr,[FATAL:audio_input_stream.cc(47)] Input device could not be opened: default
2019-06-02 08:32:57,stderr,ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
2019-06-02 08:32:57,stderr,ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
2019-06-02 08:32:57,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
2019-06-02 08:32:57,stderr,ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
2019-06-02 08:32:57,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
2019-06-02 08:32:57,stderr,ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
2019-06-02 08:32:57,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
2019-06-02 08:32:57,stderr,ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
2019-06-02 08:32:50,stderr,[FATAL:audio_input_stream.cc(47)] Input device could not be opened: default
2019-06-02 08:32:50,stderr,ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
2019-06-02 08:32:50,stderr,ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
2019-06-02 08:32:50,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
2019-06-02 08:32:50,stderr,ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
2019-06-02 08:32:50,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
2019-06-02 08:32:50,stderr,ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
2019-06-02 08:32:50,stderr,ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
2019-06-02 08:32:50,stderr,ALSA lib confmisc.c:767:(parse_card) cannot find card '0'

Wrong UTF8 encoding setting

Hi

I'm getting encoding error:

2019-01-12T19:26:30.480952308Z  ON_CONVERSATION_TURN_STARTED -                                                                                                                                                                
2019-01-12T19:26:30.482750476Z  Traceback (most recent call last):
2019-01-12T19:26:30.482861749Z    File "/gawebserver.py", line 182, in <module>                                                                                                                                                   
2019-01-12T19:26:30.483008450Z      main()
2019-01-12T19:26:30.483045945Z    File "/gawebserver.py", line 179, in main                                                                                                                                                       
2019-01-12T19:26:30.483104911Z      process_event(event)
2019-01-12T19:26:30.483134133Z    File "/gawebserver.py", line 70, in process_event
2019-01-12T19:26:30.483193397Z      print(event)
2019-01-12T19:26:30.483222601Z  UnicodeEncodeError: 'ascii' codec can't encode character '\u2026' in position 92: ordinal not in range(128)

From what I've found, it because of wrong locale env setting, and it can be fixed using PYTHONIOENCODING=utf-8. I've put it in docker run command and seems to work fine.

Error on raspberry PI 3 B+

Hi, when I try to run the container I have this error standard_init_linux.go:228: exec user process caused: exec format error. I searched some answer to this error and I found that maybe is not made for this OS.

Can't delete orphaned assistant from google home

Not a problem with the ga-webserver itself, but...

I tried to install it on my docker 1½ year ago, and didn't get it working properly, or didn't find an use-case for it,

Anyway, it havent been running for long time, but I still have a "phantom speaker" in the google home app, and when I say "ok google, syncronize devices" I get an error from this "service".

When I try to remove the "speaker" in google home app, there is no associated service, like my automower is associated with Husquarna, my roomba is associated with iRobot etc. So the speaker is orphaned.

When I try to start the container, I see in the logs {\n "error": "deleted_client",\n "error_description": "The OAuth client was deleted."\n}')

It fits with that I can't find the app in the google developer console; it's probably purged because it weren't used for more than a year.

I had a long chat with Google One Help, but they couldn't help.

I just want to get rid of the "speaker" in the list of devices in google home. Is there a way to "force-remove" devices?

Authorisation Error

Authorisation Error
Error 403: restricted_client
This app is not yet configured to make OAuth requests. To do that, set up the app’s OAuth consent screen in the Google Cloud Console.
Learn more
Request Details
access_type=offline
o2v=1
response_type=code
redirect_uri=xxxxxxxxxxxxxxxxxxxx
state=xxxxxxxxxxxxxxxxxxxxxx
prompt=consent
client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
scope=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

I followed instructions
When i first navigate to http://container:9324 and click authorization I get the above error.

Responses from Assistant

Is there any way to capture/return the responses form the assistant? I see some attempts at in the the BobsYourUncle code, but in this code there is just the return 200 ok. I was hoping I could send a command "Is the back door locked" via a text query and get the response as text or some form of a response that I could parse.

Can't resolve sound issue

@robwolff3 I tried to install the container on my Synology, but I can't seem to make the sound card work. Any ideas on implementing a dummy sound card?

Sound

Will I be able to talk to it via microphone? Just like how I talk to Ok Google in my phone?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.