from __future__ import annotations import os from pathlib import Path from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials # REQUIRED scopes based on your plan: # - read messages, move labels, mark read => modify # - send mail => send SCOPES = [ "https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/gmail.send", ] ROOT = Path(__file__).resolve().parent CREDS_PATH = Path("backend/credentials.json") TOKEN_PATH = Path("backend/token.json") def main() -> None: if not CREDS_PATH.exists(): raise FileNotFoundError( f"Missing {CREDS_PATH}. Download OAuth client JSON from Google Cloud and save as credentials.json in this folder." ) creds: Credentials | None = None # Load existing token if present if TOKEN_PATH.exists(): creds = Credentials.from_authorized_user_file(str(TOKEN_PATH), SCOPES) # Refresh or re-authenticate 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(str(CREDS_PATH), SCOPES) # Local loopback server OAuth (Desktop app) creds = flow.run_local_server(port=0) # Save token TOKEN_PATH.write_text(creds.to_json(), encoding="utf-8") print("✅ OAuth complete.") print(f"Saved token: {TOKEN_PATH}") print("Scopes granted:", creds.scopes) if __name__ == "__main__": main()