auth_setup.py

scripts/analytics/auth_setup.py(86 行)

auth_setup.py
"""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 ライセンスで配布しています。