================================================================================ GMAIL CLEANUP - CHALLENGE 3 SOLUTION Chapter 1: Configuration & API Setup Challenge: OAuth Authentication ================================================================================ PROBLEM: Create a script that performs initial OAuth setup: 1. Read credentials.json 2. Perform OAuth flow (opens browser) 3. Save token.json for future use 4. Verify that token.json was created SOLUTION: ================================================================================ File: oauth_setup.py import os import sys from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow def setup_oauth(): """Perform initial OAuth authentication.""" SCOPES = ['https://www.googleapis.com/auth/gmail.modify'] print("=" * 60) print("šŸ” GMAIL OAUTH SETUP") print("=" * 60) # Check if credentials.json exists if not os.path.exists('credentials.json'): print("āŒ credentials.json not found!") print("Download it from Google Cloud Console and save here.") return False print("\nāœ… credentials.json found") # Check if token already exists if os.path.exists('token.json'): print("āš ļø token.json already exists") response = input("Overwrite? (yes/no): ") if response.lower() != 'yes': print("āŒ Setup cancelled") return False # Perform OAuth flow print("\nšŸ” Starting OAuth flow...") print("A browser window will open. Log in and authorize the app.") try: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES ) creds = flow.run_local_server(port=0) print("\nāœ… Authorization successful!") # Save token for future use with open('token.json', 'w') as token: token.write(creds.to_json()) print("āœ… token.json created") # Verify if os.path.exists('token.json'): print(f"āœ… Verified: token.json exists ({os.path.getsize('token.json')} bytes)") print("\n" + "=" * 60) print("āœ… OAUTH SETUP COMPLETE!") print("=" * 60) print("\nYou can now use gmail_utils.get_gmail_service()") print("without needing to authorize again!") return True except Exception as e: print(f"āŒ OAuth failed: {e}") return False if __name__ == "__main__": success = setup_oauth() sys.exit(0 if success else 1) HOW IT WORKS ================================================================================ 1. CHECKS CREDENTIALS - Verifies credentials.json exists - This is the OAuth client ID/secret from Google Cloud 2. RUNS OAUTH FLOW - Calls InstalledAppFlow.from_client_secrets_file() - Opens browser to Google login page - You authorize the app to access your Gmail 3. SAVES TOKEN - After authorization, saves access token to token.json - Token lasts ~1 hour (auto-refreshes) - Removes need to log in every time 4. VERIFIES SUCCESS - Checks that token.json was created - Shows file size to confirm RUNNING THE SCRIPT ================================================================================ python oauth_setup.py Output: ============================================================ šŸ” GMAIL OAUTH SETUP ============================================================ āœ… credentials.json found šŸ” Starting OAuth flow... A browser window will open. Log in and authorize the app. [Browser opens, you log in and click "Allow"] āœ… Authorization successful! āœ… token.json created āœ… Verified: token.json exists (1024 bytes) ============================================================ āœ… OAUTH SETUP COMPLETE! ============================================================ You can now use gmail_utils.get_gmail_service() without needing to authorize again! SECURITY NOTES ================================================================================ āš ļø IMPORTANT: - token.json contains access token (sensitive!) - Add token.json to .gitignore - Never commit token.json to Git - Treat like a password If token.json is compromised: 1. Delete token.json 2. Revoke access: https://myaccount.google.com/permissions 3. Run oauth_setup.py again to get new token ================================================================================