I'm trying to set up an app for personal use to send reminder emails to Google Calendar event attendees. According to Google's app verification exceptions, I should not need to verify an app for personal use. However, my access token keeps expiring after 7 days, and my attempts to refresh the token have been in vain. I realize that apps with publishing status of "Testing" expire after 7 days, but the only other option is to submit for verification. Perhaps the fact that Google Calendar API is defined as a sensitive scope means that I have to submit for verification even though I will be the only one using it?
Running the code below returns the error google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.' My token.json file contains values for token and refresh_token.
reminders.py:
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '.env'))
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
def main():
"""Shows basic usage of the Google Calendar API.
Prints the start and name of the next 10 events on the user's calendar.
"""
flow = Flow.from_client_secrets_file(
os.path.join(basedir, 'credentials.json'), SCOPES)
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true')
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
os.path.join(basedir, 'credentials.json'), SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('calendar', 'v3', credentials=creds)
