Google Drive Uploader CLI

Uma ferramenta CLI de alto desempenho escrita em Go para enviar arquivos ao Google Drive. Ela suporta arquivos grandes (até 50 GB) e faz o gerenciamento automático de diretórios.

Recursos

  • Suporte a arquivos grandes: envios recomeçáveis para transferências confiáveis.
  • Gerenciamento de pastas: cria automaticamente a pasta se ela não existir no Drive.
  • Seguro: utiliza o fluxo padrão de autenticação OAuth 2.0.
  • Pronto para automação: caminho configurável para o token, ideal para CI/CD e CronJobs.

Pré-requisitos

  • Go 1.20 ou superior
  • Um projeto no Google Cloud com a API do Google Drive habilitada
  • Um arquivo oauth-client-config.json (também conhecido como client_secret.json) obtido no Console do Google Cloud

Instalação

# Clonar o repositório
git clone https://github.com/eliasmeireles/google-drive-uploader.git
cd google-drive-uploader

# Compilar o binário
go build -o uploader ./cmd/uploader

Obtendo as credenciais

Antes de usar o uploader, você precisa de dois arquivos: client-secret.json (credenciais OAuth) e token.json (token de autorização do usuário).

Etapa 1: Criar as credenciais OAuth (client-secret.json)

  1. Acesse o Google Cloud Console

  2. Crie um novo projeto ou selecione um existente

  3. Ative a Google Drive API:

    • Vá em APIs e Serviços > Biblioteca
    • Procure por “Google Drive API”
    • Clique em Ativar
  4. Crie credenciais OAuth 2.0:

    • Vá em APIs e Serviços > Credenciais

    • Clique em Criar credenciais > ID do cliente OAuth

    • Se solicitado, configure a tela de consentimento OAuth:

      • Tipo de usuário: Externo (ou Interno se for Google Workspace)
      • Preencha os campos obrigatórios (nome do app, e-mail de suporte, etc.)
      • Adicione seu e-mail em Usuários de teste se o tipo for Externo
    • Tipo de aplicativo: Aplicativo de área de trabalho

    • Dê um nome (exemplo: “Google Drive Uploader”)

    • Clique em Criar

  5. Faça o download das credenciais:

    • Clique no ícone de download (⬇️)
    • Salve o arquivo como client-secret.json

Exemplo de client-secret.json:

{
  "installed": {
    "client_id": "SEU_CLIENT_ID.apps.googleusercontent.com",
    "project_id": "seu-projeto",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "SEU_CLIENT_SECRET",
    "redirect_uris": [
      "http://localhost"
    ]
  }
}

Etapa 2: Gerar o token OAuth (token.json)

Use a flag --token-gen para gerar o token separadamente. A ferramenta abrirá automaticamente o navegador e cuidará do processo de autorização.

./uploader --token-gen --client-secret ./client-secret.json

Após a autorização, o arquivo token.json será salvo no diretório atual. Esse arquivo contém o token de acesso, token de atualização e credenciais — portanto, **você só precisa do token.json ** para futuros envios.

{
  "access_token": "ya29.a0AfH6SMB...",
  "token_type": "Bearer",
  "refresh_token": "1//0gZ9X...",
  "expiry": "2025-12-24T10:30:00.000Z",
  "client_id": "SEU_CLIENT_ID...",
  "client_secret": "SEU_CLIENT_SECRET..."
}

[!IMPORTANTE] Mantenha client-secret.json e token.json seguros. Nunca os envie para o controle de versão (Git, por exemplo).

[!DICA] Em ambientes automatizados (Docker, Kubernetes), gere o token.json localmente e monte-o como volume ou secret.

Uso

Primeira execução (autenticação)

Na primeira execução, o programa solicitará que você autorize o aplicativo via navegador. Após isso, o token.json será salvo automaticamente.

Upload básico

./uploader --root-folder-id "SEU_FOLDER_ID" caminho/do/arquivo.zip

Com cliente explícito

Se o token.json já contém as credenciais, não é necessário --client-secret. Mas, se quiser, pode especificar:

./uploader \
  --client-secret ./client-secret.json \
  --root-folder-id "SEU_FOLDER_ID" \
  caminho/do/arquivo.zip

Upload em lote (diretório)

./uploader \
  --workdir "./backups" \
  --root-folder-id "ROOT_ID" \
  --delete-on-success

Automação e caminhos padrão

A ferramenta busca arquivos de configuração nos seguintes locais:

  • Token: /etc/google-drive-uploader/token.json
  • Credenciais: /etc/google-drive-uploader/client-secret.json (opcional — só é necessário para gerar um novo token)

[!NOTA] Em ambientes automatizados (Docker/Kubernetes), apenas o token.json é necessário.

Exemplo de CronJob no Kubernetes

Execute backups automáticos no Kubernetes usando um CronJob:

apiVersion: v1
kind: Secret
metadata:
  name: google-drive-uploader-config
stringData:
  token.json: |
    {
      "access_token": "<ACCESS_TOKEN>",
      "token_type": "Bearer",
      "refresh_token": "<REFRESH_TOKEN>",
      "expiry": "<EXPIRY_DATE>",
      "client_id": "<CLIENT_ID>",
      "client_secret": "<CLIENT_SECRET>"
    }
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: google-drive-backup
spec:
  schedule: "0 4 * * *" # Todos os dias às 04:00
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: uploader
              image: ghcr.io/eliasmeireles/cli/google-drive-uploader:latest
              args:
                - --workdir
                - /backups
                - --root-folder-id
                - "SEU_FOLDER_ID"
                - --folder-name
                - "MEUS_BACKUPS"
                - --smart-organize
                - --delete-on-success
              volumeMounts:
                - name: config
                  mountPath: /etc/google-drive-uploader
                  readOnly: true
          volumes:
            - name: config
              secret:
                secretName: google-drive-uploader-config

[!NOTA] Crie um Secret chamado google-drive-uploader-config contendo apenas o token.json. Nenhum outro arquivo é necessário.

Uso com Docker

Também é possível executar o uploader diretamente via Docker:

docker run --rm \
  -v /caminho/token.json:/etc/google-drive-uploader/token.json:ro \
  -v /caminho/dados:/data \
  ghcr.io/eliasmeireles/cli/google-drive-uploader:latest \
  --workdir /data \
  --root-folder-id "SEU_FOLDER_ID" \
  --smart-organize \
  --delete-on-success

Esse comando:

  • Monta o token.json em modo somente leitura (:ro)
  • Monta o diretório local em /data
  • Envia todos os arquivos dentro de /data automaticamente

Organização inteligente

A flag --smart-organize organiza automaticamente os arquivos com base em padrões de nome. Por exemplo: meu_banco_backup_20251224_084205.tar.gzMEU_BANCO/2025-12-24/meu_banco_backup_20251224_084205.tar.gz

./uploader \
  --workdir "./backups" \
  --root-folder-id "ROOT_ID" \
  --smart-organize \
  --delete-on-success

Modo limpeza

O modo --cleanup remove pastas antigas com base em uma política de retenção — ideal para manter apenas os backups mais recentes.

Exemplo:

# Mantém apenas o backup mais recente
./uploader --cleanup --keep 1 --match yyyy-MM-dd --root-folder-id "ROOT_ID"

# Mantém os 3 backups mais recentes
./uploader --cleanup --keep 3 --match yyyyMMdd --root-folder-id "ROOT_ID"

Exemplo de estrutura:

Pasta Raiz
├── Serviço A
│   ├── 2025-01-10  ← removida
│   ├── 2025-01-15  ← removida
│   └── 2025-01-20  ← mantida
└── Serviço B
    ├── 2025-01-12  ← removida
    └── 2025-01-18  ← mantida

[!AVISO] O modo limpeza move pastas para a lixeira do Google Drive. Elas podem ser restauradas, mas use com cuidado.

Flags disponíveis

FlagDescriçãoPadrão
--root-folder-idID da pasta raiz no Google Drive.Obrigatório
--client-secretCaminho para o client-secret.json (necessário apenas para gerar um novo token)./etc/google-drive-uploader/client-secret.json
--token-pathCaminho do arquivo de token OAuth 2.0.token.json ou /etc/google-drive-uploader/token.json
--workdirDiretório local com os arquivos a enviar.-
--smart-organizeOrganização automática (Serviço/Data/Arquivo).false
--delete-on-successExclui o arquivo local após upload bem-sucedido.false
--delete-on-doneExclui o arquivo local mesmo em caso de falha.false
--folder-nameNome da subpasta a ser criada ou usada.-
--file-nameNome com o qual o arquivo será salvo no Drive.Nome local
--cleanupAtiva o modo limpeza (remove backups antigos).false
--keepNúmero de pastas recentes a manter (no modo limpeza).1
--matchPadrão de data para identificar pastas (ex.: yyyy-MM-dd, yyyyMMdd).yyyy-MM-dd