"""OAuthユーザー認証の初回セットアップ(最初に1回だけ実行)。
ブラウザが開くので、対象の GA4 プロパティと Search Console プロパティに
アクセス権を持つ Google アカウントでログインして許可する。
成功するとトークンファイル(リフレッシュトークン入り)が生成され、
以降 main.py はこのトークンで無人実行できる。
前提:
- Google Cloud で OAuth クライアントID(種類: デスクトップ アプリ)を作成し、
JSON をダウンロードして、設定ファイルの analytics.oauth_client_file のパスに配置済み。
- OAuth 同意画面の公開ステータスが「テスト」のままだと、リフレッシュトークンが
短期間で失効することがある。無人実行を続けるなら「本番環境」にしておく。
使い方:
(プロジェクトのルートで実行する)
python -X utf8 scripts/analytics/auth_setup.py # 認証(トークンファイルが無ければ)
python -X utf8 scripts/analytics/auth_setup.py --force # 既存のトークンファイルを無視して再認証
"""
from __future__ import annotations
import argparse
import os
import sys
import common
def main() -> int:
parser = argparse.ArgumentParser(description="OAuthユーザー認証セットアップ")
parser.add_argument("--config", default=None, help="設定ファイルのパス(既定: プロジェクトのルートの config.yaml。読むのは analytics: 節)")
parser.add_argument("--force", action="store_true", help="既存のトークンファイルを無視して再認証")
args = parser.parse_args()
cfg = common.load_config(args.config)
client_file = cfg.get("oauth_client_file")
token_file = cfg.get("oauth_token_file")
if not client_file or not os.path.exists(client_file):
print(f"[ERROR] OAuthクライアントJSONがありません: {client_file}")
print("→ Google Cloud → APIとサービス → 認証情報 → OAuthクライアントID")
print(" (種類: デスクトップ アプリ)を作成し、JSONを上記のパスに配置してください。")
return 2
if not token_file:
print("[ERROR] 設定ファイルの analytics: 節に oauth_token_file がありません。")
return 2
if os.path.exists(token_file) and not args.force:
print(f"[INFO] トークンファイルは既に存在します: {token_file}")
print(" 再認証したい場合は --force を付けてください。")
return 0
# 未インストール時に分かりやすいメッセージを出すため、ここで import する
try:
from google_auth_oauthlib.flow import InstalledAppFlow
except ImportError:
print("[ERROR] google-auth-oauthlib が未インストールです。")
print("→ プロジェクトのルートで pip install -r requirements.txt を実行してください。")
return 2
print("ブラウザを開いて認証します。GA4とSearch Consoleにアクセス権のある")
print("Googleアカウントでログインし、アクセスを許可してください...")
flow = InstalledAppFlow.from_client_secrets_file(client_file, common.SCOPES)
# access_type=offline + prompt=consent でリフレッシュトークンを確実に取得する
creds = flow.run_local_server(
port=0,
access_type="offline",
prompt="consent",
)
with open(token_file, "w", encoding="utf-8") as f:
f.write(creds.to_json())
print(f"\n[OK] 認証成功。トークンファイルを保存しました: {token_file}")
print(" これで `python -X utf8 scripts/analytics/main.py` を無人実行できます。")
print(" このファイルは秘密情報です。コミット・共有・公開しないでください。")
if not creds.refresh_token:
print("[WARN] リフレッシュトークンが取得できませんでした。")
print(" --force で再認証するか、同意画面の公開ステータスを確認してください。")
return 0
if __name__ == "__main__":
sys.exit(main())
MIT ライセンスで配布しています。