Spaces:
Sleeping
Sleeping
| 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() | |