test_ticktick_auth.py•5.72 kB
#!/usr/bin/env python3
"""
Test TickTick Authentication
This script tests your TickTick OAuth credentials without creating anything.
"""
import os
from ticktick.oauth2 import OAuth2
from ticktick.api import TickTickClient
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Fix for TickTick API endpoint change (signin -> signon)
# See: https://github.com/lazeroffmichael/ticktick-py/issues/56
def new_login(self, username, password):
"""Fixed login method using 'signon' endpoint instead of deprecated 'signin'"""
import requests
url = self.BASE_URL + 'user/signon'
user_info = {'username': username, 'password': password}
parameters = {'wc': True, 'remember': True}
print(f"\n [DEBUG] Attempting login to: {url}")
print(f" [DEBUG] Username: {username}")
# Make request directly to see status code
raw_response = requests.post(url, json=user_info, params=parameters, headers=self.HEADERS, cookies=self.cookies)
print(f" [DEBUG] Response status code: {raw_response.status_code}")
print(f" [DEBUG] Response body: {raw_response.text[:200]}")
# Now use the normal method
response = self.http_post(url, json=user_info, params=parameters, headers=self.HEADERS)
self.access_token = response['token']
self.cookies['t'] = self.access_token
# Monkey patch the login method
TickTickClient._login = new_login
def test_auth():
print("=" * 50)
print("Testing TickTick Authentication")
print("=" * 50)
# Check environment variables
print("\n1. Checking environment variables...")
client_id = os.getenv('TICKTICK_CLIENT_ID')
client_secret = os.getenv('TICKTICK_CLIENT_SECRET')
redirect_uri = os.getenv('TICKTICK_REDIRECT_URI', 'http://127.0.0.1:8080')
username = os.getenv('TICKTICK_USERNAME')
password = os.getenv('TICKTICK_PASSWORD')
missing = []
if not client_id:
missing.append("TICKTICK_CLIENT_ID")
if not client_secret:
missing.append("TICKTICK_CLIENT_SECRET")
if not username:
missing.append("TICKTICK_USERNAME")
if not password:
missing.append("TICKTICK_PASSWORD")
if missing:
print("❌ Missing environment variables:")
for var in missing:
print(f" - {var}")
print("\nAdd these to your .env file and try again.")
return False
print("✓ All environment variables found")
print(f" Client ID: {client_id[:10]}...")
print(f" Username: {username}")
print(f" Redirect URI: {redirect_uri}")
# Test OAuth2 initialization
print("\n2. Initializing OAuth2...")
print("\n" + "=" * 50)
print("IMPORTANT: OAuth Authorization Flow")
print("=" * 50)
print("A browser should open automatically.")
print("If not, manually visit the authorization URL shown.")
print("\nSteps:")
print("1. Authorize the app in your browser")
print("2. You'll be redirected to: http://127.0.0.1:8080/...")
print("3. Copy the ENTIRE redirect URL from your browser")
print("4. Paste it back here when prompted")
print("=" * 50)
try:
auth_client = OAuth2(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri
)
print("\n✓ OAuth2 authorization complete!")
except KeyboardInterrupt:
print("\n\n❌ Authorization cancelled by user")
return False
except Exception as e:
print(f"\n❌ OAuth2 authorization failed: {e}")
print("\nTroubleshooting:")
print(" 1. Make sure you copied the ENTIRE redirect URL")
print(" 2. Check your redirect URI in TickTick developer console matches: http://127.0.0.1:8080")
print(" 3. Try running the test again")
return False
# Test TickTick client initialization
print("\n3. Connecting to TickTick API...")
print(" (This may open a browser for authorization...)")
try:
client = TickTickClient(username, password, auth_client)
print("✓ Successfully connected!")
except Exception as e:
print(f"❌ Connection failed: {e}")
print(f"\nError type: {type(e).__name__}")
# Show more details if available
import traceback
print("\nFull error details:")
traceback.print_exc()
print("\nTroubleshooting:")
print(" 1. Check your username/password are correct")
print(" 2. Check your Client ID/Secret are correct")
print(" 3. Check your redirect URI matches: http://127.0.0.1:8080")
print(" 4. Try logging into TickTick web/app directly to verify credentials")
return False
# Test data retrieval
print("\n4. Retrieving your TickTick data...")
try:
profile_id = client.profile_id
inbox_id = client.inbox_id
timezone = client.time_zone
print(f"✓ Profile ID: {profile_id}")
print(f"✓ Inbox ID: {inbox_id}")
print(f"✓ Timezone: {timezone}")
# Get existing projects
projects = client.state.get('projects', [])
print(f"\n✓ Found {len(projects)} existing projects:")
for project in projects[:5]: # Show first 5
print(f" - {project.get('name', 'Unnamed')}")
# Get existing tasks
tasks = client.state.get('tasks', [])
print(f"\n✓ Found {len(tasks)} active tasks")
except Exception as e:
print(f"❌ Data retrieval failed: {e}")
return False
print("\n" + "=" * 50)
print("✅ Authentication Test PASSED!")
print("=" * 50)
print("\nYou're ready to run: python ticktick_setup.py --setup")
return True
if __name__ == "__main__":
test_auth()