setup_oauth.py script handles OAuth configuration for all Google services used by Morning Brain Starter in a single authorization flow.
Command Syntax
Options
Force regeneration of the OAuth token even if
GOOGLE_REFRESH_TOKEN already exists in .env. Use this when you need to add new scopes or fix authentication issues.By default, the script skips OAuth if you already have a valid
GOOGLE_REFRESH_TOKEN.Prerequisites
Before running this script, you need:-
Google Cloud Project with APIs enabled:
- Google Calendar API
- Google Meet API
- Gmail API
- Google Docs API
-
OAuth 2.0 Client credentials (Desktop app type)
- Client ID
- Client secret
-
Environment file with credentials:
Usage Examples
Initial OAuth setup
Regenerate token
If you already have a token but need to update permissions:Check if token exists
Run without--regenerate when token exists:
OAuth Scopes
The script requests all required Google API scopes in a single authorization:Endpoint:
https://www.googleapis.com/auth/calendar.readonlyRead calendar events, attendees, and metadata.Endpoint:
https://www.googleapis.com/auth/calendar.eventsCreate and modify calendar events. Needed for:- Adding Meet links to events
- Accepting/declining invitations
- Adding transcription reminders to descriptions
Endpoint:
https://www.googleapis.com/auth/meetings.space.settingsConfigure Google Meet settings. Needed for:- Enabling automatic transcription on Meet spaces
Endpoint:
https://www.googleapis.com/auth/gmail.readonlyRead-only access to Gmail. Needed for:- Fetching recent email metadata
Endpoint:
https://www.googleapis.com/auth/documents.readonlyRead Google Docs content. Needed for:- Fetching meeting transcriptions from linked Docs
- Importing transcription text
All scopes are requested together. You only need to authorize once, even if you add new features that use different APIs.
How It Works
- Load environment: Reads
resources/secrets/.envforGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET - Check existing token: Looks for
GOOGLE_REFRESH_TOKENin.env - Skip or proceed: If token exists and
--regeneratenot specified, exits early - Create OAuth flow: Uses
google-auth-oauthlibto build authorization flow - Open browser: Launches local web server and opens browser for consent
- User authorizes: You log in to Google and approve permissions
- Receive callback: Local server receives OAuth callback with authorization code
- Exchange for token: Trades authorization code for refresh token
- Save to .env: Writes
GOOGLE_REFRESH_TOKENtoresources/secrets/.env
OAuth Flow Details
The script uses the OAuth 2.0 Installed Application Flow:- Authorization endpoint:
https://accounts.google.com/o/oauth2/auth - Token endpoint:
https://oauth2.googleapis.com/token - Redirect URI:
http://localhost(random port assigned) - Client type: Desktop application
Asana Configuration
Asana OAuth is separate. This script only handles Google services. To configure Asana:
- Get a Personal Access Token from Asana App Settings
- Add to
.envmanually:
Exit Codes
- 0: Success - token saved or already exists
- 1: Error - missing credentials or OAuth failure
Error Conditions
When to Regenerate Token
Runsetup_oauth.py --regenerate when:
- ✅ You get 403 “Insufficient permissions” errors
- ✅ You’ve enabled additional APIs in Google Cloud Console
- ✅ Your token has been revoked or expired
- ✅ You need to authorize with a different Google account
- ✅ Scope requirements have changed (after updating the codebase)
Security Best Practices
-
Keep
.envprivate: Theresources/secrets/directory is gitignored. Never commit credentials. - Use restricted API keys: In Google Cloud Console, restrict your OAuth client to specific APIs.
- Review permissions: Understand what each scope allows before authorizing.
- Rotate tokens periodically: Regenerate tokens every few months as a security practice.
- Revoke unused tokens: Go to Google Account Permissions to revoke old tokens.
Configuration Files
The script modifies:resources/secrets/.env- Adds or updatesGOOGLE_REFRESH_TOKEN
resources/secrets/.env- ReadsGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET
Related Commands
- calendar - Uses Calendar API scopes
- email - Uses Gmail API scope
- reset-config - Removes all credentials and tokens
- run-morning - Uses all configured APIs
Troubleshooting
Browser doesn’t open
If the browser doesn’t open automatically:- Look for a URL in the terminal output
- Copy and paste it into your browser manually
- Complete authorization in the browser
”redirect_uri_mismatch” error
In Google Cloud Console, ensure your OAuth client allows:http://localhost- Redirect URIs with arbitrary ports
”Access blocked: Authorization Error”
Your OAuth consent screen might be in “Testing” mode:- Go to Google Cloud Console → OAuth consent screen
- Add your email to “Test users”
- Or publish the app (not recommended for personal use)
Token not saved
Check file permissions:resources/secrets/ directory exists:
Advanced Usage
Programmatic token refresh
All scripts automatically refresh access tokens using the refresh token. You don’t need to re-runsetup_oauth.py for routine token refreshes.
Example from code:
Multiple Google accounts
To use different Google accounts:-
Create separate
.envfiles:resources/secrets/.env.personalresources/secrets/.env.work
-
Run setup for each:
-
Switch between environments when running commands:
The scripts don’t natively support multiple accounts. This is a workaround using symbolic links or environment variables.