autool/authorize_gmail.py
2026-06-17 19:44:18 +08:00

145 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Gmail OAuth 授权脚本
用于首次配置 Google OAuth 并生成 token.json 文件。
运行此脚本后,浏览器会自动打开 Google 授权页面。
"""
import os
import sys
from pathlib import Path
# 添加项目根目录到 Python 路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
try:
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
except ImportError:
print("❌ 错误:缺少依赖库")
print("请运行以下命令安装:")
print(" pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client")
sys.exit(1)
# Gmail API 权限范围(只读)
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
# 凭据文件路径
CREDENTIALS_FILE = project_root / "DroidBot" / "guiagent_core" / "credentials.json"
TOKEN_FILE = project_root / "DroidBot" / "guiagent_core" / "token.json"
def authorize_gmail():
"""执行 Gmail OAuth 授权流程"""
print("=" * 60)
print("Gmail OAuth 授权工具")
print("=" * 60)
creds = None
# 检查是否已有 token
if TOKEN_FILE.exists():
print(f"\n✓ 发现已有 token 文件:{TOKEN_FILE}")
try:
creds = Credentials.from_authorized_user_file(str(TOKEN_FILE), SCOPES)
print("✓ Token 加载成功")
except Exception as e:
print(f"⚠️ Token 加载失败:{e}")
creds = None
# 如果 token 无效或不存在,重新授权
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
print("\n⏳ Token 已过期,正在刷新...")
try:
creds.refresh(Request())
print("✓ Token 刷新成功")
except Exception as e:
print(f"⚠️ Token 刷新失败:{e}")
print("将进行重新授权...")
creds = None
if not creds:
# 检查 credentials.json 是否存在
if not CREDENTIALS_FILE.exists():
print(f"\n❌ 错误:凭据文件不存在")
print(f"路径:{CREDENTIALS_FILE}")
print("\n请按照以下步骤操作:")
print("1. 阅读文档docs/GOOGLE_OAUTH_SETUP.md")
print("2. 在 Google Cloud Console 创建 OAuth 凭据")
print("3. 下载 credentials.json 并放置到上述路径")
sys.exit(1)
print(f"\n✓ 凭据文件已找到:{CREDENTIALS_FILE}")
print("\n⏳ 开始 OAuth 授权流程...")
print("提示:浏览器将自动打开,请登录 Google 账号并授权")
print(" 如果看到「此应用未经 Google 验证」,点击「高级」→「继续」")
try:
flow = InstalledAppFlow.from_client_secrets_file(
str(CREDENTIALS_FILE), SCOPES
)
creds = flow.run_local_server(port=0)
print("\n✓ 授权成功!")
except Exception as e:
print(f"\n❌ 授权失败:{e}")
sys.exit(1)
# 保存 token
TOKEN_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(TOKEN_FILE, 'w') as token:
token.write(creds.to_json())
print(f"✓ Token 已保存到:{TOKEN_FILE}")
# 测试 API 访问
print("\n⏳ 正在测试 Gmail API 访问...")
try:
service = build('gmail', 'v1', credentials=creds)
# 获取用户信息
profile = service.users().getProfile(userId='me').execute()
email_address = profile.get('emailAddress')
# 获取标签列表
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
print("✓ Gmail API 访问成功!")
print(f" 授权邮箱:{email_address}")
print(f" 标签数量:{len(labels)}")
if labels:
print(f" 部分标签:{', '.join([l['name'] for l in labels[:5]])}")
except Exception as e:
print(f"❌ Gmail API 访问失败:{e}")
sys.exit(1)
print("\n" + "=" * 60)
print("✓ Gmail OAuth 配置完成!")
print("=" * 60)
print(f"\n配置文件位置:")
print(f" 凭据文件:{CREDENTIALS_FILE}")
print(f" Token 文件:{TOKEN_FILE}")
print(f"\n⚠️ 安全提示:")
print(f" - 这些文件包含敏感信息,请勿提交到版本库")
print(f" - 已在 .gitignore 中配置忽略规则")
print(f" - Token 有效期 1 小时,过期后会自动刷新")
print(f"\n现在可以使用 GuiAgent 的邮箱验证码功能了!")
if __name__ == "__main__":
try:
authorize_gmail()
except KeyboardInterrupt:
print("\n\n⚠️ 授权已取消")
sys.exit(1)
except Exception as e:
print(f"\n❌ 发生错误:{e}")
import traceback
traceback.print_exc()
sys.exit(1)