#!/usr/bin/env python3 """ Enhanced Google Calendar Credential Diagnostics & Refresh Tool This script diagnoses calendar authentication issues and refreshes credentials. Usage locally: python3 refresh_credentials.py Usage via SSH on HuggingFace: ssh -i ~/.ssh/id_ed25519 pgits-voicecal-ai@ssh.hf.space cd /app && python refresh_credentials.py """ import sys import os sys.path.insert(0, '/app') sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from datetime import datetime import requests def check_environment_variables(): """Check all required environment variables.""" print("\n" + "=" * 70) print("STEP 1: Environment Variables Check") print("=" * 70) required_vars = { 'GOOGLE_CLIENT_ID': os.environ.get('GOOGLE_CLIENT_ID'), 'GOOGLE_CLIENT_SECRET': os.environ.get('GOOGLE_CLIENT_SECRET'), 'GOOGLE_REFRESH_TOKEN': os.environ.get('GOOGLE_REFRESH_TOKEN'), 'GOOGLE_ACCESS_TOKEN': os.environ.get('GOOGLE_ACCESS_TOKEN'), 'GOOGLE_TOKEN_EXPIRY': os.environ.get('GOOGLE_TOKEN_EXPIRY'), } all_present = True for var_name, var_value in required_vars.items(): if var_value: # Show first 20 chars for security display_value = f"{var_value[:20]}..." if len(var_value) > 20 else var_value print(f"โœ… {var_name}: {display_value}") else: print(f"โŒ {var_name}: MISSING") all_present = False if not all_present: print("\nโš ๏ธ Missing required environment variables!") print(" These must be configured in HuggingFace Secrets") return False return True def test_token_refresh(): """Test token refresh with Google OAuth API.""" print("\n" + "=" * 70) print("STEP 2: Token Refresh Test") print("=" * 70) refresh_token = os.environ.get('GOOGLE_REFRESH_TOKEN') client_id = os.environ.get('GOOGLE_CLIENT_ID') client_secret = os.environ.get('GOOGLE_CLIENT_SECRET') print("๐Ÿ”„ Attempting to refresh access token via Google OAuth API...") data = { 'client_id': client_id, 'client_secret': client_secret, 'refresh_token': refresh_token, 'grant_type': 'refresh_token' } 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) from datetime import timedelta new_expiry = datetime.utcnow() + timedelta(seconds=expires_in) print("โœ… Token refresh SUCCESSFUL!") print(f" New Access Token: {new_access_token[:30]}...") print(f" Expires in: {expires_in} seconds ({expires_in//3600} hours)") print(f" Expiry Time: {new_expiry.isoformat()}") print("\n๐Ÿ“‹ Update these in HuggingFace Secrets:") print(f" GOOGLE_ACCESS_TOKEN={new_access_token}") print(f" GOOGLE_TOKEN_EXPIRY={new_expiry.isoformat()}") return True, new_access_token, new_expiry.isoformat() else: print(f"โŒ Token refresh FAILED!") print(f" Status: {response.status_code}") print(f" Error: {response.text}") if response.status_code == 400: error_data = response.json() if error_data.get('error') == 'invalid_grant': print("\n๐Ÿ” DIAGNOSIS: invalid_grant error") print(" Possible causes:") print(" 1. Refresh token has been revoked") print(" 2. OAuth consent screen needs re-approval") print(" 3. Redirect URI mismatch in Google Cloud Console") print("\n๐Ÿ› ๏ธ SOLUTION:") print(" Re-authenticate: https://pgits-voicecal-ai-v3.hf.space/auth/login") elif response.status_code == 401: print("\n๐Ÿ” DIAGNOSIS: Authentication error") print(" Possible causes:") print(" 1. Wrong GOOGLE_CLIENT_ID or GOOGLE_CLIENT_SECRET") print(" 2. OAuth app not enabled in Google Cloud Console") print("\n๐Ÿ› ๏ธ SOLUTION:") print(" Verify credentials in Google Cloud Console") return False, None, None except Exception as e: print(f"โŒ Exception: {e}") import traceback traceback.print_exc() return False, None, None def test_calendar_auth(): """Test calendar authentication using app's CalendarAuth.""" print("\n" + "=" * 70) print("STEP 3: Calendar Service Authentication Test") print("=" * 70) try: from app.calendar.auth import CalendarAuth from app.config import settings print("๐Ÿ“‹ Initializing CalendarAuth...") auth = CalendarAuth() print("๐Ÿ” Loading credentials...") credentials = auth.load_credentials() if not credentials: print("โŒ No credentials found!") print(" DIAGNOSIS: Environment variables may be missing") print(" SOLUTION: Ensure all GOOGLE_* vars are in HuggingFace Secrets") return False print(f"โœ… Credentials loaded!") print(f" Token Expiry: {credentials.expiry}") print(f" Token Expired: {credentials.expired}") print(f" Has Refresh Token: {credentials.refresh_token is not None}") # Try to get calendar service print("\n๐Ÿ”ง Attempting to get calendar service...") service = auth.get_calendar_service() if not service: print("โŒ Calendar service is None!") return False print("โœ… Calendar service obtained!") # Test API call print("\n๐Ÿงช Testing Calendar API call (list calendars)...") calendars = service.calendarList().list().execute() print(f"โœ… API call successful! Found {len(calendars.get('items', []))} calendars") return True except ValueError as e: if "No valid credentials" in str(e): print(f"โŒ FATAL: {e}") print("\n๐Ÿ” DIAGNOSIS: No valid credentials available") print(" This is the error you're seeing in production") print("\n๐Ÿ› ๏ธ SOLUTION:") print(" 1. Check all GOOGLE_* environment variables are set") print(" 2. Run token refresh (STEP 2)") print(" 3. Update GOOGLE_ACCESS_TOKEN and GOOGLE_TOKEN_EXPIRY") print(" 4. Or re-authenticate via /auth/login") else: print(f"โŒ ValueError: {e}") return False except Exception as e: print(f"โŒ Exception: {e}") import traceback traceback.print_exc() return False def main(): print("=" * 70) print("๐Ÿ”ง VOICECAL.AI - GOOGLE CALENDAR AUTH DIAGNOSTICS") print("=" * 70) print(f"Timestamp: {datetime.now().isoformat()}") print(f"Environment: {os.environ.get('APP_ENV', 'unknown')}") print() # Step 1: Check environment variables env_ok = check_environment_variables() if not env_ok: print("\nโŒ CRITICAL: Environment variables missing. Cannot proceed.") print(" Add them to HuggingFace Secrets first.") return # Step 2: Test token refresh refresh_ok, new_token, new_expiry = test_token_refresh() # Step 3: Test calendar authentication auth_ok = test_calendar_auth() # Summary print("\n" + "=" * 70) print("DIAGNOSTIC SUMMARY") print("=" * 70) print(f"Environment Variables: {'โœ… OK' if env_ok else 'โŒ FAILED'}") print(f"Token Refresh: {'โœ… OK' if refresh_ok else 'โŒ FAILED'}") print(f"Calendar Auth: {'โœ… OK' if auth_ok else 'โŒ FAILED'}") print("=" * 70) if env_ok and refresh_ok and not auth_ok: print("\n๐Ÿ’ก RECOMMENDATION:") print(" The token refresh worked, but calendar auth failed.") print(" Update these secrets in HuggingFace:") print(f" GOOGLE_ACCESS_TOKEN={new_token}") print(f" GOOGLE_TOKEN_EXPIRY={new_expiry}") print(" Then restart the space.") elif not refresh_ok: print("\n๐Ÿ’ก RECOMMENDATION:") print(" Token refresh failed. You need to re-authenticate.") print(" Visit: https://pgits-voicecal-ai-v3.hf.space/auth/login") elif auth_ok: print("\n๐ŸŽ‰ SUCCESS! Calendar authentication is working properly!") print("\n" + "=" * 70) if __name__ == "__main__": main()