Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

How to resolve the issue with the new API's #13

Closed
cskiwi opened this issue May 24, 2021 · 23 comments
Closed

How to resolve the issue with the new API's #13

cskiwi opened this issue May 24, 2021 · 23 comments

Comments

@cskiwi
Copy link

cskiwi commented May 24, 2021

For users having issues with the updated heart rate and sleep permissions:

I tried first adding the required scopes to the sensor.py removing my token file but then I got a invalid_scope error, I searched a bit, but couldn't figure out why.

After some more messing around I found a method that seems to work

Required;

  • Setup the HACS integration a first time so it is authorized (and the token file is generated)
  • This requires some JSON knowledge and now how
  • full "tutorial" must be done in 3599 seconds (so basically within 1 hour, we are going to change the access token, and the get refreshed every hour)

Let's goo!

  1. Go to oauthplayground

  2. Click on "Step 1 Select & authorize APIs"
    Scroll down to Fitness API v1
    Normally all scopes should be enabled with read and write (this isn't fully needed, but I didn't had the time to fully figure out what needs to be enabled)
    If not, these are the ones that worked for me:
    image

  3. Click on "Auhtorize APIs" and go trough the authorization steps

  4. In step 2, click on Exchange authorization code for tokens

  5. On the right you should see something like this:
    image
    copy the full json part on the bottom (with the access_token, scope, ...)

  6. open your .<name>_google_fit.token file. This should be on the same level as your configuration.yaml file (I suggest you create a copy and format it, for easy working and having a backup)

  7. Paste the copied json in the token_response part (this should have the same keys, maybe different order)

  8. Copy the full access_token (yellow in reference screenshot), full refresh_token (purple in reference screenshot) to the upper part of the json

  9. Copy the following scopes (green in reference screenshot) to the scopes part (remove the ones you didn't authorize):

  "scopes": [
    "https://www.googleapis.com/auth/fitness.location.write",
    "https://www.googleapis.com/auth/fitness.sleep.read",
    "https://www.googleapis.com/auth/fitness.heart_rate.read",
    "https://www.googleapis.com/auth/fitness.location.read",
    "https://www.googleapis.com/auth/fitness.activity.read",
    "https://www.googleapis.com/auth/fitness.body.write",
    "https://www.googleapis.com/auth/fitness.activity.write",
    "https://www.googleapis.com/auth/fitness.body.read",
    "https://www.googleapis.com/auth/fitness.sleep.write",
    "https://www.googleapis.com/auth/fitness.heart_rate.write"
  ],
  1. Save it (the token file doesn't have to be on a single line, formatted also works)
  2. Restart Homeassistant and this should be working :slight_smile:

Refrenced screenshot of my <name>.google_fit.token file (not my full tokens obvisouly) :
image

I'm still waiting for a new token token to be generated, but this should give any issue (from my knowledge of these tokens, but then again I don't understand why the scope was giving issues)

@vmanuel
Copy link
Owner

vmanuel commented Jun 6, 2021

I thik it is because now they are restricted scopes...

https://support.google.com/cloud/answer/9110914#restricted-scopes&zippy=%2Cgmail-drive-and-google-fit-apis

@astronaut63
Copy link

astronaut63 commented Jun 10, 2021

I tried this manual solution as posted above and on https://community.home-assistant.io/t/google-fit-support/4556/180 and it worked initially but then stopped
I also did some digging into the methods for getting tokens and then coded 2 standalone python routines

The first was using the same method as the various google fit sensors (calling oauth2client.client.Oauth2Webserverflow and then ...step1_get_device_and_user code() from the Google api python client) .. when this works then it gives you a code to enter at www.google.com/device. With this routine it was quick to try different sets of scopes and see which work/didn't work and also use the debugger to confirm that it is the google server rejecting the requests

In the second method I used oauth2client.tools.run_flow which then takes you through the browser based authorisation and returns the credentials needed. The routine then writes these into a file whcih can then be renamed to match your expected google fit sensor token file .

Results - as we have all found, any use of the new scopes with the get_device_and_user_code routine fails (and fails after the data has been sent across to https://oauth2.googleapis.com/device/code
Looking at the documentation https://developers.google.com/identity/protocols/oauth2/limited-input-device it does state that this method does support a limited number of scopes (and does not list any fitness scopes) -so perhaps we were lucky that the sensor worked at all

Better news is that the second method (generating the token file) has been running for 48 hours now and is still collecting steps, heart rate and sleep data.

Code for second routine

import os
REQUIREMENTS = [
    'google-api-python-client==1.6.4',
    'oauth2client==4.0.0',
    'httplib2'
]

# Sensor base attributes.

CONF_CLIENT_ID = '32...................apps.googleusercontent.com'
CONF_CLIENT_SECRET = '..................................5'



TOKEN_FILE = ''

# Endpoint scopes required for the sensor.
# Read more: https://developers.google.com/fit/rest/v1/authorization

SCOPES = ["https://www.googleapis.com/auth/fitness.location.write",
          "https://www.googleapis.com/auth/fitness.sleep.read",
          "https://www.googleapis.com/auth/fitness.heart_rate.read",
          "https://www.googleapis.com/auth/fitness.location.read",
          "https://www.googleapis.com/auth/fitness.activity.read",
          "https://www.googleapis.com/auth/fitness.body.write",
          "https://www.googleapis.com/auth/fitness.activity.write",
          "https://www.googleapis.com/auth/fitness.body.read",
          "https://www.googleapis.com/auth/fitness.sleep.write",
          "https://www.googleapis.com/auth/fitness.heart_rate.write" ]

def do_authentication():
    """Notify user of actions and authenticate.

    Notify user of user_code and verification_url then poll until we have an
    access token.
    """
    from oauth2client import client as oauth2client
    from oauth2client import file as oauth2file
    from oauth2client.file import Storage
    from oauth2client.tools import run_flow
    import google.oauth2.credentials

    oauth = oauth2client.OAuth2WebServerFlow(
        client_id=CONF_CLIENT_ID,
        client_secret=CONF_CLIENT_SECRET,
        scope=SCOPES,
        redirect_uri='urn:ietf:wg:oauth:2.0:oob',
    )

    storage = Storage('google_fit.token')
    # Open a web browser to ask the user for credentials.
    credentials = run_flow(oauth, storage)
    assert credentials.access_token is not None
    return credentials.access_token

    token = get_access_token()
    credentials = google.oauth2.credentials.Credentials(token)

    TOKEN_FILE = "google_fit.token"
    storage = oauth2file.Storage(TOKEN_FILE)
    storage.put(credentials)

    return True

do_authentication()

@ranrinc
Copy link

ranrinc commented Jun 17, 2021

@astronaut63 Trying to implement the first method, however, keep getting hit by 400 error message. On AuthPlayground, if I enter my credential and id token, it will also fail to authorize it with a 400 error.

Trying to the your 2nd method but still can't figure it out how to put the code? Should I create a new py? Put it in the custom components/google_fit? The name?

Thanks for at least a solutions

@rolfberkenbosch
Copy link

@astronaut63 i try you fix, but still get the Google Fit Setup
Error: Invalid response 400. Error: invalid_scope
You will need to restart hass after fixing. error

I place the google_fit.token in the /config map and restart HA, but still the above error. Am i missing something ?

@astronaut63
Copy link

astronaut63 commented Jun 17, 2021

Some of this is covered in #15 and thanks to @firstchair for the command lines to run the routine (and to install the necessary modules)
The routine I have posted is a standalone python routine that needs to be run outside of Home Assistant e.g.
"python3 script_google_fit.py --noauth_local_webserver"
It creates a file "google_fit.token" but this will need to be renamed to match how you have named your google fit sensor (for example in my configuration file I have (the not very helpful but I am very new to HA)

- platform: google_fit
  name: Google Fit

The token file expected is .[name]_[platform]
and so my token file is then ".Google Fit_google_fit.token"

If you have created the token file and are getting the Error 400 invalid scope error then this means that the sensor.py did not find the token file and has then tried to request authorisation of the scopes using the ...step1_get_device_and_user code() in routine do_authentication (if the file exists then no call is made to do_authentication) --- so please check again the token file name

@ranrinc
Copy link

ranrinc commented Jun 18, 2021

Go it working.. Thanks, @astronaut63 @firstchair for all the help

Screen Shot 2021-06-18 at 11 44 00 AM

@Davecl
Copy link

Davecl commented Aug 5, 2021

I have created the token file (after a lot of extra steps, updating python to get oauth2 etc)
Where does this go? in HA folder? custom components?
thanks

@ranrinc
Copy link

ranrinc commented Aug 6, 2021

I have created the token file (after a lot of extra steps, updating python to get oauth2 etc)
Where does this go? in HA folder? custom components?
thanks

once you get the new token.. you need to add it to your current google fit token on your HA.

@astronaut63
Copy link

I simply copy the complete token file into the config folder (and then restart HA - usually just restarting core seems to work)

@Davecl
Copy link

Davecl commented Aug 6, 2021

Thanks.. copied it into the config folder
Seems to be working, fingers crossed

@tripplehelix
Copy link

I already have a .google.token file. Don't know if that's the reason, but this isn't creating a ._google_fit token automatically...

@Davecl
Copy link

Davecl commented Aug 19, 2021

I already have a .google.token file. Don't know if that's the reason, but this isn't creating a ._google_fit token automatically...

I think they may have changed the API again, mines stopped working

@davidjac
Copy link

Anyone else able to comment I cant get this working again either.

@Maharshi-Pathak
Copy link

Has this fix been committed to any working branch of this repo?

@sharoltd
Copy link

My sensor updated only during HA restarting. is it possible to make updating by automation?

@freitas666
Copy link

@cskiwi can you have date from sleep time and heart sensor??

@freitas666
Copy link

script_google_fit.py

do still have this script?

@Ken-dono
Copy link

Ken-dono commented Jun 15, 2022

hi guys thanks all those indications.

I still do have a problem when running the script. google seems to stop the request.

_You can't sign in to this app because it violates Google's OAuth 2.0 app security policy.
You can tell the app developer that it violates one or more of Google's validation rules.

Any ideas?

@astronaut63
Copy link

The script runs standalone e.g. in a python environment or if you look at an older post there is a link to a command line.

I ran the script 11 days s ago and it works as expected - it asks me which google account I want to use, it then warns me that the app is not yet verified by Google and then when I proceed I get promoted to tick the 10 different data types I am giving access to. This then created the new token file which I copied to Home Assistant (and restarted HA)

Just tried again and the routine to create the token it is still working
Also Home Assistant still showing approx 11 Google data items (steps, Heart rate, Sleep time , distance ....) all with live data

@Ken-dono
Copy link

image

I ran the script after adding the dependencies but after choosing the account i'm blocked by the google warning system and can't proceed.

@PoGA21
Copy link

PoGA21 commented Jul 13, 2022

Is there a video somewhere for the really stupid like me?

@Hadatko
Copy link

Hadatko commented Feb 28, 2023

HA:
image

Script:
Chyba 400: invalid_request

@Ivesvdf
Copy link

Ivesvdf commented Apr 24, 2023

I can confirm the authorization error reported earlier is still an issue when using the script.

@cskiwi cskiwi closed this as completed Jul 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests