Spaces:
Sleeping
Sleeping
| """ | |
| connect_google.py - Quick Google Sheets authentication. | |
| Run this ONCE. It opens your browser, you log in with Google, | |
| and the token is saved. After that, python main.py writes to your sheet automatically. | |
| Usage: python connect_google.py | |
| """ | |
| import os, sys, webbrowser | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| SHEET_ID = os.getenv("GOOGLE_SHEET_ID", "1Ehxt3eortehbtySdtgcSrMhCqmxIMUAmvRqSkII0HJk") | |
| STEP1_URL = "https://console.cloud.google.com/projectcreate" | |
| APIS_URL = "https://console.cloud.google.com/apis/library" | |
| CREDS_URL = "https://console.cloud.google.com/apis/credentials" | |
| SHEET_URL = f"https://docs.google.com/spreadsheets/d/{SHEET_ID}/edit" | |
| def main(): | |
| print() | |
| print("=" * 60) | |
| print(" Google Sheets Connection Setup") | |
| print(" Job Automation Agent") | |
| print("=" * 60) | |
| print() | |
| # Check if already connected | |
| if Path("google_token.json").exists(): | |
| print("Token file found. Testing connection...") | |
| if test_connection(): | |
| print() | |
| print("Already connected! Run: python main.py") | |
| return | |
| else: | |
| print("Token expired. Re-authenticating...") | |
| Path("google_token.json").unlink(missing_ok=True) | |
| if Path("google_credentials.json").exists(): | |
| print("Service account found. Testing...") | |
| if test_connection(): | |
| print("Connected via service account!") | |
| return | |
| if Path("google_oauth_client.json").exists(): | |
| print("OAuth client found. Opening browser for login...") | |
| do_oauth() | |
| return | |
| # Need to set up from scratch | |
| print("No credentials found. Let's set this up (5 minutes).") | |
| print() | |
| print("SETUP STEPS:") | |
| print("-" * 40) | |
| print() | |
| print("Step 1: Create a Google Cloud Project") | |
| print(" -> Opening https://console.cloud.google.com/projectcreate") | |
| input(" Press Enter to open browser...") | |
| webbrowser.open(STEP1_URL) | |
| print() | |
| print("Step 2: Enable required APIs") | |
| print(" -> Search for and enable:") | |
| print(" - 'Google Sheets API'") | |
| print(" - 'Google Drive API'") | |
| input(" Press Enter to open API Library...") | |
| webbrowser.open(APIS_URL) | |
| input(" Press Enter when both APIs are enabled...") | |
| print() | |
| print("Step 3: Create OAuth Credentials") | |
| print(" -> Click '+ CREATE CREDENTIALS' -> 'OAuth client ID'") | |
| print(" -> Application type: Desktop app") | |
| print(" -> Name: Job Automation Agent") | |
| print(" -> Click CREATE") | |
| print(" -> Click DOWNLOAD JSON") | |
| print(f" -> Save as 'google_oauth_client.json' in this folder:") | |
| print(f" {os.path.abspath('.')}") | |
| input(" Press Enter to open Credentials page...") | |
| webbrowser.open(CREDS_URL) | |
| input(" Press Enter after saving google_oauth_client.json here...") | |
| print() | |
| if not Path("google_oauth_client.json").exists(): | |
| print("ERROR: google_oauth_client.json not found.") | |
| print(f"Please save it to: {os.path.abspath('google_oauth_client.json')}") | |
| return | |
| print() | |
| print("IMPORTANT: Before logging in, you MUST add your email as a test user.") | |
| print("(This is why you got 'Access blocked' error)") | |
| print() | |
| print("Step 4: Add yourself as a Test User") | |
| print(" -> Go to OAuth consent screen") | |
| print(" -> Scroll to 'Test users' section") | |
| print(" -> Click '+ Add users'") | |
| print(" -> Add: saitejatirunagari@gmail.com") | |
| print(" -> Click Save") | |
| input(" Press Enter to open OAuth consent screen...") | |
| webbrowser.open("https://console.cloud.google.com/apis/credentials/consent") | |
| input(" Press Enter after adding your email as test user...") | |
| print() | |
| do_oauth() | |
| def do_oauth(): | |
| """Run the OAuth browser flow and save token.""" | |
| try: | |
| from google_auth_oauthlib.flow import InstalledAppFlow | |
| from google.auth.transport.requests import Request | |
| SCOPES = [ | |
| "https://www.googleapis.com/auth/spreadsheets", | |
| "https://www.googleapis.com/auth/drive", | |
| ] | |
| print() | |
| print("Opening browser for Google login...") | |
| print("(Log in with your Google account and click Allow)") | |
| print() | |
| flow = InstalledAppFlow.from_client_secrets_file("google_oauth_client.json", SCOPES) | |
| creds = flow.run_local_server(port=0, open_browser=True) | |
| Path("google_token.json").write_text(creds.to_json()) | |
| print("Token saved to google_token.json") | |
| if test_connection(): | |
| print() | |
| print("=" * 60) | |
| print(" Connected successfully!") | |
| print(" Run: python main.py") | |
| print(" Your Google Sheet will be updated automatically.") | |
| print(f" Sheet: {SHEET_URL}") | |
| print("=" * 60) | |
| else: | |
| print("Connection test failed. Check the sheet URL in .env") | |
| except Exception as e: | |
| print(f"OAuth failed: {e}") | |
| print() | |
| print("Try the service account method instead:") | |
| print(" python setup_google.py") | |
| def test_connection() -> bool: | |
| """Test if credentials work.""" | |
| try: | |
| import gspread | |
| from google.oauth2.service_account import Credentials as SACredentials | |
| from google.oauth2.credentials import Credentials as OAuthCredentials | |
| SCOPES = [ | |
| "https://www.googleapis.com/auth/spreadsheets", | |
| "https://www.googleapis.com/auth/drive", | |
| ] | |
| creds = None | |
| # Try service account | |
| if Path("google_credentials.json").exists(): | |
| creds = SACredentials.from_service_account_file("google_credentials.json", scopes=SCOPES) | |
| # Try OAuth token | |
| elif Path("google_token.json").exists(): | |
| from google.auth.transport.requests import Request | |
| creds = OAuthCredentials.from_authorized_user_file("google_token.json", SCOPES) | |
| if creds.expired and creds.refresh_token: | |
| creds.refresh(Request()) | |
| Path("google_token.json").write_text(creds.to_json()) | |
| if creds is None: | |
| return False | |
| client = gspread.authorize(creds) | |
| sh = client.open_by_key(SHEET_ID) | |
| print(f" Connected to: '{sh.title}'") | |
| return True | |
| except Exception as e: | |
| print(f" Connection failed: {e}") | |
| return False | |
| if __name__ == "__main__": | |
| main() | |