Broadcast message to Google Assistant speakers without interrupting music

Hmm, not sure what the issue is. Can you try mounting an folder within users home path?

You could also try replacing image tag latest with 1.0.0

I tried changing the tag to 1.0.0, which didnā€™t help.
I donā€™t understand what you mean, isnā€™t the /usr/src/config/ folder of the container already mapped to the hosts system with the -v (volumes) tag?

Also tried to put the command in a docker-compose which didnā€™t help. I wanted to check inside the container but when it finished it automatically exits. So I cant go inside the container or copy files if it should have created one.

And is the way I created my client secret alright? Or maybe I made a mistake there? This is the structure I have:

Your client_secret.json content looks correct!

What I meant is that you should try mounting another folder (from your host) that is owned by the user you are logged in with in your OS, /opt is owned by the root user. I suspect we are dealing with write/permission issues from docker container to the host folder /opt/google-assistant-broadcast/config.

Here is a example for default user (ubuntu) in Ubuntu OS, Also, IĀ“m here demonstrating how to start the docker container in interactive mode so the container does not quit after tokens.json is generated. This can help you check if the tokens.json gets created in the folder /usr/src/config inside the container, when the authentication flow ends.

  1. Start container in interactive mode and mount a folder which user ubuntu owns
docker run --rm -it \
-p 3005:3005 \
-v /home/ubuntu/google-assistant-oauth/config:/usr/src/config \
ismarslomic/google-assistant-oauth:latest \
/bin/ash
  1. Execute this command when you are inside the container
node index.js
  1. Do the authentication flow

  2. When the authentication flow is done, verify that tokens.json is created in container:

ls -al /usr/src/config
  1. Exit container by typing exit
exit
  1. Verify that the tokens.json exists at host
ls -al /home/ubuntu/google-assistant-oauth/config
1 Like

Yes apparently it were some weird permission issues.
Which is very weird because initially I executed everything with the root user which should have all the permission.

But when I executed it with the pi user (one of my users) it worked after is put sudo before each command. Thanks for your help, much appreciated!

After I got the tokens.json I was able to spin up the broadcast container. Now I have the same problem as @joolui, I always get an empty response back and no sound comes out my Nest speakers.
But this may be a problem with the new google account I created for this use case. It has all the rights like my main google account but it doesnt work yet. Iā€™ll give it some time and otherwise Iā€™ll try it with my main account. But thanks for all the troubleshooting!

  • Is it normal that those tokens expire after 1h of creation?

Glad you fixed the issue with tokens.json file. I will update the README file to get attention for new users on this topic.

Since Iā€™m not able to reproduce the error you and @joolui is facing, I donā€™t know how to help. But please let me know if you find out, so I can either make a bugfix or update docs.

I have used the same token for several weeks, without needing to recreate it.

Iā€™ll keep you posted if I find out why it doesnā€™t broadcast the messages.
What I do find very strange if I look in the Google Console Platform I see there are a few Google Assistant API request, so they go through the API but it doesnā€™t get played:


(This is with my main google account, so the owner of my Google Home)

In your setup did you have to do specific settings to tell which speakers it could broadcast to?
(I have Google Nest speakers which I can broadcast to with Google Assistant via my phone/car)
Last question, in your OAuth consent screen did you publish the APP? I did not and have it set tot external user type with myself (main google account email address) as a test user).

Can you please register new issue in Github repo, regarding questions in last post? I can provide some input on what you could try to fix the problem.

Hey @ismarslomic. Thanks for getting this back up and running. Iā€™m struggling with getting the tokens. My HASS is hosted in a docker container on a headless server. I donā€™t have a GUI, let alone a web browser, to paste the link into for the oauth credentials. When I try to use a different system with a gui (on the same network) it obviously borks at the ā€œlocalhost:3005ā€ portion of the callback. I also tried changing ā€œlocalhostā€ to the serverā€™s IP, but that also didnā€™t work.

Any idea how else i can get the token?

To obtain the access token you can start the google-assistant-oauth container on whatever machine you have access to (server, PC, Mac, etc.). This is a one time job you do to obtain the tokens file, which you need in the google-assistant-broadcast container.

If you start the google-assistant-oauth container on your headless server, copy the url to your web browser (you must be on the same network or use VPN), you can replace the localhost with the IP address of your headless server when the OAuth flow is finished and your browser is redirected.

Hope this helps!

Unfortunately, when I do that I get the following error:

Authorization Error
Error 400: invalid_request
device_id and device_name are required for private IP: http://10.10.1.100:3005/oauth2callback
Learn more

Google oath doesnā€™t support private ipā€™s so you at minimum need to do the token generation from the machine running the container

I was able to install Firefox into a container and generate the file. However, now Iā€™m getting an ā€œunauthenticatedā€ issue. Hereā€™s my output:

[2022-06-13T23:06:01.833Z] Sending message (en-GB): Broadcast Hello world!!
[2022-06-13T23:06:02.070Z] [ERROR] Error while broadcasting: Error: 16 UNAUTHENTICATED: Failed to retrieve auth metadata with error: invalid_grant
    at Object.callErrorFromStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/client.js:391:49)
    at Object.onReceiveStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)
    at /usr/src/app/node_modules/@grpc/grpc-js/build/src/call-stream.js:187:78
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
  code: 16,
  details: 'Failed to retrieve auth metadata with error: invalid_grant',
  metadata: Metadata { internalRepr: Map(0) {}, options: {} }
}
[2022-06-13T23:06:02.072Z] [OK] Conversation Completed
[2022-06-13T23:07:28.673Z] Sending message (en-GB): Broadcast Hello world!!
[2022-06-13T23:07:28.904Z] [ERROR] Error while broadcasting: Error: 16 UNAUTHENTICATED: Failed to retrieve auth metadata with error: invalid_grant
    at Object.callErrorFromStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/client.js:391:49)
    at Object.onReceiveStatus (/usr/src/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)
    at /usr/src/app/node_modules/@grpc/grpc-js/build/src/call-stream.js:187:78
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
  code: 16,
  details: 'Failed to retrieve auth metadata with error: invalid_grant',
  metadata: Metadata { internalRepr: Map(0) {}, options: {} }
}

This doesnā€™t seem to be the language issue that you referred to previously; any thoughts on what this one is?

ā€“Edit-- This is your cue to recreate the credentials and try again.

Thanks for your work developing this. Itā€™s working great now!

1 Like

Still not possible to only play on a specific speaker? :slight_smile:

Not as far as I know

Anyone managed to get this to work now that OOB is deprecated?

ismarslomic/google-assistant-broadcast still works perfectly.

You canā€™t really broadcast to a specific device with the way you have it setup because broadcast: ā€œtrueā€ is sent to Google Assistant. When you do that GA interprets the entire message as broadcast text. If you allowed us to send a command then we could do ā€œbroadcast to {{ a_room_defined_in_google_home }} {{ message }}ā€ which would be interpreted as a command and then the device/room would be parsed from the beginning of the message and the rest would be sent as a broadcast to an individual or group of devices.

I made this comment on an issue in github. Hopefully you see it and reconsider.

Also, what are the chances you will create this as an addon so itā€™s easier to get installed?

Release v1.0.7 supports sending commands and broadcast to specific speakers. Please give it a try and see if it works out for you.

I dont have any concrete plans moving this to a custom component nor hass addon. I agree there is some treshold to get it up and running, but if you are techy its quite easy. It also depends on a javascript library for Google Assistant SDK, and that doesnt fit directly into an python environment.

But if someone has time to support on creating custom component, that would be very nice! I could also find time to support it!

I see the update and I appreciate the change. I also noticed that quite a few others that were watching github have already tested the change. Thatā€™s great.

Hopefully somebody can pickup the banner and create an addon. For those of us running HA OS that are techy but really hands off it would be a great addition. There was an addon version of assistant relay. Maybe that author (@Apipa169) would be interested in creating an addon for this.

Iā€™ve been looking for a way to send command via home-assistant to google assistant as there is no way to integrate a light/fan I have into home assistant. Playing playing with this and Iā€™m running into an issue sending the message.

Iā€™ve set up and retrieved the docker container for Oauth.
The google-broadast container is running with the environment variable APPEND_BROADCAST_TO_MESSAGE=false
When I try to send a command via curl nothing happens. When looking at the broadcast logs I see the following:

~$ curl -X POST http://localhost:8085/broadcast  -d '{"message":"turn on hot water heater"}'  -H "Content-Type: application/json" 
^C 
~$ docker logs 2294bb79ebdd 
Paste your code: [2022-12-30T16:20:52.654Z] Sending message (en-GB): turn on hot water heater 
[2022-12-30T16:20:52.702Z] Opening OAuth URL. Return here with your code.

Not to sure why it doesnā€™t proceed from here, iā€™m not convinced I have the oath correct either, as when i run that container, each time it asks me to go to the URL, and accept that i trust my app so i click continue, then have to return to console

EDIT:
Issue was on my end, I ran the container passing the wrong volume in. Recreated and itā€™s working now.

Love this project, thank you so much.

1 Like