Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Calendar Token problem #96

Closed
dk1010101 opened this issue Jan 14, 2025 · 16 comments
Closed

Google Calendar Token problem #96

dk1010101 opened this issue Jan 14, 2025 · 16 comments

Comments

@dk1010101
Copy link

dk1010101 commented Jan 14, 2025

I recently (14 days ago) built the display and connected it to google calendar following the procedure in the instructions. After seven days the calendar stopped updating and i got the following error:

google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})

I thought that perhaps i did something wrong so i deleted the token and followed the instructions again to create a new one. That also worked for seven days (actually seven days and 15 minutes looking at the token creation time and the last update on the screen) and now i am again getting the same error:

2025-01-14:14:19:03 INFO     [screen-calendar-get.py:98] Fetching Google Calendar Events
Traceback (most recent call last):
  File "/home/dan/waveshare-epaper-display/screen-calendar-get.py", line 119, in <module>
    main()
  File "/home/dan/waveshare-epaper-display/screen-calendar-get.py", line 101, in main
    calendar_events = provider.get_calendar_events()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/waveshare-epaper-display/calendar_providers/google.py", line 54, in get_calendar_events
    service = build('calendar', 'v3', credentials=self.get_google_credentials(), cache_discovery=False)
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/waveshare-epaper-display/calendar_providers/google.py", line 39, in get_google_credentials
    credentials.refresh(Request())
  File "/home/dan/waveshare-epaper-display/.venv/lib/python3.11/site-packages/google/oauth2/credentials.py", line 319, in refresh
    ) = reauth.refresh_grant(
        ^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/waveshare-epaper-display/.venv/lib/python3.11/site-packages/google/oauth2/reauth.py", line 349, in refresh_grant
    _client._handle_error_response(response_data, retryable_error)
  File "/home/dan/waveshare-epaper-display/.venv/lib/python3.11/site-packages/google/oauth2/_client.py", line 69, in _handle_error_response
    raise exceptions.RefreshError(
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been
expired or revoked.'})
---------------------------------------
⚠️ERROR GETTING CALENDAR INFO, STOPPING.
---------------------------------------

Any ideas how to stop this from happening? I looked on google portal but i cannot see where that i can change the lifespan for tokens etc but then i shouldn't have to, that is what refresh tokens are for, right? The token is a Desktop token and looking at the portal i cannot see anything that tells me if it had expired or not.

Googling suggests that this is to do with the "app" being in "testing" and to fix this one would need to make it production. This sounds like a total overkill as i would be the only one using it and having google verify the app is nonsensical. How did other solve this problem?

Any pointers will be most welcome.

@mendhak
Copy link
Owner

mendhak commented Jan 14, 2025

I have a post here with screenshots, check that this matches up with what you are doing: #19 (comment)

You should see a credentials.json and also a token.pickle on disk. Have a peek inside them with cat. The credentials.json should have a client id, and a client secret somewhere in there. The token.pickle will appear gibberish but you should see strings saying token, and refresh_token in there.

The idea behind the refresh token is that you don't have to keep redoing the instructions, it refreshes itself (and works fine normally, so 'something is happening to cause your refreshes to not happen 🫤)

@dk1010101
Copy link
Author

That is exactly what i followed.

i could not use the "TV" token as it repored an error, when screen-calendar-get.py was run:

Error 400: invalid_request

   Localhost URI is not allowed for 'NATIVE_DEVICE' client type.

and if i take the URL and paste it in to the browser i get:

image

so i could not proceed. the desktop token, however, worked, if only for seven days.
the desktop token worked fine and if i look at the picke object it is all fine too:

image

it is just that the token has expired.

perhpas there is some setting at the application level that makes a difference? at, say, "OAuth consent screen"? what scopes does the app need? if the are restricted/sensitive then test app needs verification and before that all tokens will only live for a week:

Authorizations by a test user will expire seven days from the time of consent. If your OAuth client requests [an offline access type](https://developers.google.com/identity/protocols/oauth2/web-server#offline) and receives a refresh token, that token will also expire.

Basically, as i understand it, Google say that their non-prod tokens and refresh-tokens only last for a week and that after that we need to recreate them. Isn't this a problem everyone else is seeing?

@jmason
Copy link
Contributor

jmason commented Jan 16, 2025

For what it's worth, I'm using a Desktop OAuth credential and haven't had to redo it in years. However my app is "in production". I think you may need to do that -- and possibly allow just your own Google user to access it?

@mendhak
Copy link
Owner

mendhak commented Jan 16, 2025

That's a good shout jmason thanks. In my own setup indeed my Oauth setting is 'in production'.

Image

If that's indeed it, then I probably need to add that to the instructions in the comment earlier.

@dk1010101
Copy link
Author

That is what i thought but it felt like an overkill so I thought i would ask.
Shame they want everyone to do this as testing is perfectly ok for one-person use... imnho :)

Thank you!

@dk1010101
Copy link
Author

dk1010101 commented Jan 20, 2025

I went and had a look what i need to do to make the "app" be in production. I need to provide app logo, app home page, link to privacy documents which are publically available, link to pub available terms of service, i need to register the domain those docs are on... and that is just the first screen. i tried not answering but it would not let me proceed until i have everything in place.

Is it really supposed to be this difficult? or did i select some other setting that made it this difficult? can someone remember how they registered the app? i am guessing anyone new will have the same problem...

@mendhak
Copy link
Owner

mendhak commented Jan 20, 2025

Could you just delete that authorised domain bit, use the trash icon next to it?

I'm looking at my setup and I don't have a domain set up next to it. No logo either.

Image

@dk1010101
Copy link
Author

It won't let me pass withouth app home page, privacy policy or service link. domain is not an issue - yet. it was in the above as i was playing with the form, trying to find what i could get away with. sorry about that.

Image

@mendhak
Copy link
Owner

mendhak commented Jan 24, 2025

To add to all this faffing about, I've noticed that my entire OAuth Consent Screen layout has completely changed to the 'new experience', a different layout, same information but multiple pages.

In any case I still don't have those fields as mandatory. I'm wondering why it's the case for you. Do you have other secrets that are generated for non-desktop application, something like that?

Could you go to Google Console top right at the top and generate a brand new project and start over? It might be that something has flagged this particular oauth as more verification required, but if you start in a new project maybe it's fresh and you can generate just one credential file.

@mendhak
Copy link
Owner

mendhak commented Jan 24, 2025

To show what I mean, in this project I've only got one client and it's a Desktop app. If Desktop app doesn't work, try limited input type instead.

Image

@dk1010101
Copy link
Author

Good suggestion.

I just created a brand new project and went through the steps once again. out of interest, what scope should be selected? i selected calendar.events.owned.readonly but i am not sure if that is correct. It is possible that some scopes require all the info i was being asked for before and some don't...

interestingly, now when i go and look at the scopes nothing appears to be selected but the display works with the new credentials. This is really bad from google as i cannot see the scope i selected even though i know that i selected it (since i took a screenshot). let's see if it works first and then if i will be able to make it "production". given that no scopes are listed i am guessing that i will be able to make it prod withouth verification. i'll check in the morning...

@mendhak
Copy link
Owner

mendhak commented Jan 25, 2025

No scopes!

Image

@mendhak
Copy link
Owner

mendhak commented Jan 25, 2025

I wonder if the presence of the scopes 'triggers' a more strict check.

@dk1010101
Copy link
Author

creating a completely new project and then doing everything from scratch appears to have worked. desktop token was ok, tv one was not. i chose calendar.events.owned.readonly as the scope - which worked - and then i was able to move from testing to production.

i think the reason it didn't work before was the scope choice but i cannot find a way of seeing what scope i chose last time. it just doesn't appear on any of the screens on the portal. may be worth exctending the documentation to include portal side too or perhaps it was just me 😆

thank you all for all the suggestions and help

@dk1010101
Copy link
Author

I wonder if the presence of the scopes 'triggers' a more strict check.

i think the choice matters however i had to provide a scope or google would not let me create the token. when look now, i can no longer see what scope i chose. My scope screen now looks exactly like yours - blank.

@mendhak
Copy link
Owner

mendhak commented Feb 1, 2025

Alright that was an adventure and a half ha. I've also added 'create a new project' to the comments.

Honestly it feels more and more difficult working with GCP, just to read some calendar entries. Contrast this with Outlook's which has been seamless and works really well.

@mendhak mendhak closed this as completed Feb 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants