youtube-publish は何をしますか?
YouTube Data API v3 アップローダー(SDK非依存、プレーンな fetch、再開可能チャンクアップロード)。バッチ処理向けに構築:デフォルトで非公開、sha256 台帳により再実行時の重複投稿を防止、メタデータ検証、ドライラン、クォータ認識機能を備えています。
初回セットアップ(ユーザーが行う作業。エージェントは行いません)
- Google Cloud Console:プロジェクトを作成し、YouTube Data API v3 を有効化、デスクトップアプリ タイプの OAuth クライアントID を作成します。
- クライアント情報をスクリプトに提供します(コミットしないでください):
export YOUTUBE_CLIENT_ID=... YOUTUBE_CLIENT_SECRET=...(またはダウンロードした JSON をリポジトリ外に保持し、--client-secretsで指定します)。 - チャンネルを一度認可します:
同意画面が開き、リダイレクトを 127.0.0.1 でキャッチし(PKCE + state チェック)、リフレッシュトークンをモード 600 で保存します。トークンが出力されることはありません。node scripts/auth.mjs --token-file .youtube-token.json
ワークフロー
# 1. ドライラン:メタデータを検証し、ファイルのハッシュを計算し、スキップ/アップロード計画とクォータコストを表示
node scripts/upload.mjs --jobs jobs.json --dry-run
# 2. アップロード(デフォルトで非公開)
node scripts/upload.mjs --jobs jobs.json --token-file .youtube-token.json
# 単一ファイル
node scripts/upload.mjs --file publish/short.mp4 --title "How I automated my edits" --tags shorts,automation --privacy unlisted
jobs.json:
[
{ "file": "publish/short-01.mp4", "title": "...", "description": "...", "tags": ["shorts"], "privacy": "private" },
{ "file": "publish/short-02.mp4", "title": "...", "privacy": "private", "publishAt": "2026-11-01T17:00:00Z" }
]
相対パスの file は、ジョブファイルのフォルダを基準に解決されます。
ルール
render-qcに合格し、ユーザーが承認したファイルのみアップロードします。- デフォルトのプライバシーは
private(非公開)です。public(公開)は、ユーザーが明示的に要求し、--allow-publicを渡した場合のみ許可されます。スケジュール公開動画(publishAt)はprivateでなければなりません。YouTube がその時刻に公開に切り替えます。 - 必ず最初に
--dry-runを実行し、計画をユーザーに表示してください。 - トークン、クライアントシークレット、
.env*ファイル、台帳を出力、ログ記録、コミットしないでください。リポジトリの.gitignoreは*token*.json、*credentials*.json、*client_secret*.json、.env*、*ledger*.jsonをカバーしています。 - 台帳(
.youtube-upload-ledger.json)は、投稿された内容の信頼できる情報源です。アップロードごとに保存されます。「再試行」のために削除しないでください。--force-duplicateは、ユーザーが本当に2回目のコピーを必要とする場合にのみ使用します。 - クォータ:プロジェクトのデフォルトは1日あたり10,000ユニットで、1回のアップロードのコストはこれまで1,600ユニット(1日あたり約6アップロード)です。
--max-uploads(デフォルト6)は、クォータを消費し尽くす前に実行を停止します。--units-per-uploadは、Google がコストを変更した場合の推定値を調整します。quotaExceededが発生すると実行が停止し、残りのジョブは翌日再実行できます(台帳は完了済みのジョブをスキップします)。 - タイトル:プレースホルダー(TODO、untitled、
{{...}})不可、最大100文字、<または>不可。タグの合計は最大500文字。lint がこれを強制します。 - 未検証の API プロジェクトでは、Google がアプリを監査するまでアップロードが非公開に強制される場合があります。すべてのアップロードが非公開で返ってくる場合は、その旨をユーザーに伝えてください。
確認
各結果には videoId(非公開の間は https://youtu.be/<id> で開けます)または skipped 理由が含まれます。node scripts/upload.mjs --check-auth はアップロードせずに認証情報をテストします。