""" Google Drive Auto-Uploader using OAuth2 refresh token. Works with personal Google accounts (not just Workspace). """ import os import json from google.oauth2.credentials import Credentials from google.auth.transport.requests import Request from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload # Scopes required for Drive upload SCOPES = ['https://www.googleapis.com/auth/drive'] def get_drive_service(): """ Creates a Google Drive API service using OAuth2 refresh token. Requires 3 env vars: GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_DRIVE_REFRESH_TOKEN """ client_id = os.getenv("GOOGLE_OAUTH_CLIENT_ID", "").strip() client_secret = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET", "").strip() refresh_token = os.getenv("GOOGLE_DRIVE_REFRESH_TOKEN", "").strip() if not all([client_id, client_secret, refresh_token]): missing = [] if not client_id: missing.append("GOOGLE_OAUTH_CLIENT_ID") if not client_secret: missing.append("GOOGLE_OAUTH_CLIENT_SECRET") if not refresh_token: missing.append("GOOGLE_DRIVE_REFRESH_TOKEN") print(f"ERROR: Missing env vars: {', '.join(missing)}", flush=True) return None # Debug: Print first few chars to verify (Don't log full secrets!) print(f"DEBUG: Client ID: {client_id[:5]}... (len={len(client_id)})", flush=True) print(f"DEBUG: Client Secret: {client_secret[:3]}... (len={len(client_secret)})", flush=True) print(f"DEBUG: Refresh Token: {refresh_token[:5]}... (len={len(refresh_token)})", flush=True) try: creds = Credentials( token=None, refresh_token=refresh_token, client_id=client_id, client_secret=client_secret, token_uri="https://oauth2.googleapis.com/token", scopes=SCOPES ) # Refresh the access token creds.refresh(Request()) service = build('drive', 'v3', credentials=creds) print("✅ Google Drive connected (OAuth2)!", flush=True) return service except Exception as e: print(f"❌ Failed to connect to Google Drive: {e}", flush=True) return None def upload_to_drive(file_path, folder_id=None): """ Uploads a file to Google Drive using the user's own account. Args: file_path: Path to the file to upload folder_id: Google Drive folder ID Returns: The file URL on Google Drive, or None if upload failed """ if not folder_id: folder_id = os.getenv("GOOGLE_DRIVE_FOLDER_ID") if not folder_id: print("ERROR: GOOGLE_DRIVE_FOLDER_ID not set!", flush=True) return None service = get_drive_service() if not service: return None filename = os.path.basename(file_path) file_size_mb = os.path.getsize(file_path) / (1024 * 1024) print(f"📤 Uploading {filename} ({file_size_mb:.1f} MB) to Google Drive...", flush=True) file_metadata = { 'name': filename, 'parents': [folder_id] } media = MediaFileUpload( file_path, mimetype='video/mp4', resumable=True, chunksize=10 * 1024 * 1024 # 10MB chunks ) try: file = service.files().create( body=file_metadata, media_body=media, fields='id, webViewLink' ).execute() file_id = file.get('id') file_link = file.get('webViewLink', f"https://drive.google.com/file/d/{file_id}/view") print(f"✅ Upload SUCCESS: {filename}", flush=True) print(f"📎 Link: {file_link}", flush=True) return file_link except Exception as e: print(f"❌ Upload FAILED: {e}", flush=True) return None