#!/usr/bin/env python3 """ Google OAuth Token Refresh Utility for VoiceCal.ai This utility refreshes Google OAuth access tokens using the stored refresh token. Useful for debugging authentication issues and getting fresh tokens. Usage: python3 scripts/refresh_google_token.py """ import requests import json import os from datetime import datetime, timedelta def refresh_google_token(): """Refresh Google OAuth access token using refresh token.""" # Get current credentials from environment refresh_token = os.environ.get('GOOGLE_REFRESH_TOKEN') client_id = os.environ.get('GOOGLE_CLIENT_ID') client_secret = os.environ.get('GOOGLE_CLIENT_SECRET') if not all([refresh_token, client_id, client_secret]): print("❌ Missing required environment variables:") print(f" GOOGLE_REFRESH_TOKEN: {'✓' if refresh_token else '✗'}") print(f" GOOGLE_CLIENT_ID: {'✓' if client_id else '✗'}") print(f" GOOGLE_CLIENT_SECRET: {'✓' if client_secret else '✗'}") return None print("🔧 Google OAuth Token Refresh Utility") print("=" * 50) print(f"Client ID: {client_id[:12]}...") print(f"Refresh token: {refresh_token[:20]}...") print() # Prepare refresh request data = { 'client_id': client_id, 'client_secret': client_secret, 'refresh_token': refresh_token, 'grant_type': 'refresh_token' } print("🔄 Requesting new access token from Google...") try: response = requests.post('https://oauth2.googleapis.com/token', data=data) print(f"Response status: {response.status_code}") if response.status_code == 200: tokens = response.json() new_access_token = tokens['access_token'] expires_in = tokens.get('expires_in', 3600) # Calculate new expiry time new_expiry = datetime.utcnow() + timedelta(seconds=expires_in) print("✅ SUCCESS! Token refresh completed") print("=" * 50) print("📋 New token details:") print(f" Access Token: {new_access_token[:20]}...{new_access_token[-10:]}") print(f" Expires in: {expires_in} seconds ({expires_in//3600} hours)") print(f" Expiry time: {new_expiry.isoformat()}") print() print("🔧 Environment variables to update:") print(f" GOOGLE_ACCESS_TOKEN={new_access_token}") print(f" GOOGLE_TOKEN_EXPIRY={new_expiry.isoformat()}") print() print("💡 Copy these values to your HuggingFace Space environment variables") return { 'access_token': new_access_token, 'expires_in': expires_in, 'token_expiry': new_expiry.isoformat() } else: print("❌ FAILED to refresh token") print(f"Status: {response.status_code}") print(f"Error: {response.text}") print() if response.status_code == 400: error_data = response.json() if error_data.get('error') == 'invalid_grant': print("🔍 Possible causes:") print(" - Refresh token has expired (rare)") print(" - Refresh token was revoked by user") print(" - System clock is incorrect") elif response.status_code == 401: print("🔍 Possible causes:") print(" - Invalid client_id or client_secret") print(" - OAuth app configuration mismatch") print(" - Redirect URIs don't match (for new HF space)") print() print("🛠️ Check Google Cloud Console:") print(" 1. Verify client credentials") print(" 2. Update redirect URIs to match current space URL") print(" 3. Ensure OAuth app is enabled") return None except Exception as e: print(f"❌ Exception occurred: {e}") return None def test_calendar_access(): """Test if calendar access works with current credentials.""" print("\n🧪 Testing calendar access...") try: from app.calendar.auth import CalendarAuth auth = CalendarAuth() service = auth.get_calendar_service() print("✅ Calendar authentication successful!") return True except Exception as e: print(f"❌ Calendar authentication failed: {e}") return False if __name__ == "__main__": print("VoiceCal.ai - Google OAuth Token Refresh Utility") print("=" * 60) # Refresh token result = refresh_google_token() # Test calendar access if running in app environment try: test_calendar_access() except ImportError: print("\n💡 Run from app directory to test calendar access") print(" cd /app && python3 scripts/refresh_google_token.py") print("\n" + "=" * 60) print("🏁 Token refresh utility completed")