O que youtube-publish faz?
Ferramenta de upload da YouTube Data API v3 sem dependência de SDK (usando apenas fetch, upload retomável em blocos). Construída para lotes: privado por padrão, um registro SHA256 para que uma reexecução nunca publique duplicatas, lint de metadados, simulação e consciência de cota.
Configuração única (feita pelo usuário, não pelo agente)
- Console Google Cloud: crie um projeto, ative a YouTube Data API v3 e crie um ID de cliente OAuth do tipo Aplicativo para desktop.
- Forneça o cliente aos scripts sem versioná-lo:
export YOUTUBE_CLIENT_ID=... YOUTUBE_CLIENT_SECRET=...(ou mantenha o JSON baixado fora do repositório e passe--client-secrets). - Autorize o canal uma vez:
Abre a página de consentimento, captura o redirecionamento em 127.0.0.1 (PKCE + verificação de estado), armazena o token de atualização com modo 600. O token nunca é exibido.node scripts/auth.mjs --token-file .youtube-token.json
Fluxo de trabalho
# 1. simulação: valida metadados, gera hash dos arquivos, mostra plano de upload/pulo e custo de cota
node scripts/upload.mjs --jobs jobs.json --dry-run
# 2. upload (privado por padrão)
node scripts/upload.mjs --jobs jobs.json --token-file .youtube-token.json
# arquivo único
node scripts/upload.mjs --file publish/short.mp4 --title "Como automatizei minhas edições" --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" }
]
Caminhos de file relativos são resolvidos em relação à pasta do arquivo de jobs.
Regras
- Faça upload apenas de arquivos que passaram em
render-qce foram aprovados pelo usuário. - A privacidade padrão é
private.publicé recusado a menos que o usuário tenha solicitado explicitamente e você tenha passado--allow-public. Vídeos agendados (publishAt) devem serprivate; o YouTube os torna públicos nesse horário. - Sempre execute
--dry-runprimeiro e mostre o plano ao usuário. - Nunca exiba, registre ou faça commit de tokens, client secrets, arquivos
.env*ou o registro. O.gitignoredo repositório cobre*token*.json,*credentials*.json,*client_secret*.json,.env*e*ledger*.json. - O registro (
.youtube-upload-ledger.json) é a fonte da verdade para o que foi publicado. Ele é salvo após cada upload individual. Não o exclua para "tentar novamente"; use--force-duplicateapenas se o usuário realmente quiser uma segunda cópia. - Cota: um projeto recebe 10.000 unidades/dia por padrão e um upload histórico custa 1.600 unidades (cerca de 6 uploads/dia).
--max-uploads(padrão 6) interrompe uma execução antes de queimar a cota;--units-per-uploadajusta a estimativa se o Google alterar o custo. EmquotaExceeded, a execução para e os jobs restantes podem ser reexecutados no dia seguinte (o registro pula os já concluídos). - Títulos: sem placeholders (TODO, untitled,
{{...}}), no máximo 100 caracteres, sem<ou>. O total de tags no máximo 500 caracteres. O lint aplica isso. - Projetos de API não verificados podem forçar uploads para privado até que o Google audite o aplicativo; avise o usuário se todo upload voltar como privado.
Verificação
Cada resultado tem um videoId (abra https://youtu.be/<id> enquanto ainda estiver privado) ou um motivo de skipped. node scripts/upload.mjs --check-auth testa as credenciais sem fazer upload.