Pular para conteúdo

DRIVE_DOWNLOAD - Download de Arquivos do Google Drive

O que é este Node?

O DRIVE_DOWNLOAD é o node responsável por baixar arquivos do Google Drive e disponibilizá-los em base64 para uso nos seus flows, permitindo processar, enviar ou manipular documentos armazenados na nuvem.

Por que este Node existe?

Acessar arquivos armazenados no Google Drive manualmente é trabalhoso. O DRIVE_DOWNLOAD existe para:

  1. Automação de Envios: Baixar contratos/documentos para enviar via WhatsApp
  2. Processamento: Obter arquivos para análise ou conversão
  3. Backup Local: Fazer cópia de segurança de arquivos importantes
  4. Integração: Usar arquivos do Drive em outras ferramentas do flow

Como funciona internamente?

Quando o DRIVE_DOWNLOAD é executado, o sistema:

  1. Autentica: Valida o OAuth2 token do Google
  2. Localiza arquivo: Usa o fileId para identificar o arquivo
  3. Faz download: Requisita conteúdo usando alt=media
  4. Converte: Transforma o ArrayBuffer em string base64
  5. Retorna: Conteúdo base64 pronto para uso
  6. Se erro: Lança exceção (arquivo não encontrado, sem permissão, etc)

Código interno (google-executors.service.ts:604-615):

case 'download':
  const downloadResult = await drive.files.get({
    fileId: data.fileId,
    alt: 'media',
  }, {
    responseType: 'arraybuffer',
  });

  return {
    success: true,
    content: Buffer.from(downloadResult.data as ArrayBuffer).toString('base64'),
  };

Quando você DEVE usar este Node?

Use DRIVE_DOWNLOAD sempre que precisar de acessar conteúdo de arquivos do Drive:

Casos de uso

  1. Enviar documentos: "Baixar contrato padrão e enviar para cliente"
  2. Processar dados: "Baixar planilha Excel para extrair informações"
  3. Gerar relatórios: "Obter template de relatório para preencher dados"

Quando NÃO usar DRIVE_DOWNLOAD

  • Arquivo muito grande: Pode estourar limite de memória do flow
  • Sem fileId: Precisa ter o ID do arquivo (use drive_list ou drive_search antes)
  • Apenas visualizar: Use webViewLink ao invés de baixar

Parâmetros Detalhados

accessToken (string, obrigatório)

O que é: Token de acesso OAuth2 do Google para autenticar a requisição.

Como obter: Através do fluxo OAuth2 com os escopos https://www.googleapis.com/auth/drive.file ou https://www.googleapis.com/auth/drive.readonly.

Flow completo para testar:

{
  "name": "Teste Drive Download - AccessToken",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Configurar Tokens",
        "parameters": {
          "variableName": "tokens",
          "value": {
            "access": "ya29.a0AfH6SMB...",
            "refresh": "1//0g...",
            "fileId": "1a2b3c4d5e6f7g8h9i0j"
          }
        }
      }
    },
    {
      "id": "drive_download_1",
      "type": "google_drive",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Baixar Arquivo",
        "parameters": {
          "operation": "download",
          "accessToken": "{{tokens.access}}",
          "refreshToken": "{{tokens.refresh}}",
          "fileId": "{{tokens.fileId}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Arquivo baixado! Tamanho: {{length(drive_download_1.content)}} caracteres"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "drive_download_1" },
    { "source": "drive_download_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Substitua tokens e fileId por valores reais 2. Execute o flow 3. Espera: Mensagem com tamanho do conteúdo baixado

refreshToken (string, obrigatório)

O que é: Token de atualização OAuth2 usado para renovar o accessToken quando ele expira.

Flow completo para testar:

{
  "name": "Teste Drive Download - Auto Refresh",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "drive_download_1",
      "type": "google_drive",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Download",
        "parameters": {
          "operation": "download",
          "accessToken": "{{user.googleAccessToken}}",
          "refreshToken": "{{user.googleRefreshToken}}",
          "fileId": "{{arquivo.id}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar Arquivo",
        "parameters": {
          "message": "Aqui está o arquivo solicitado:",
          "mediaBase64": "{{drive_download_1.content}}",
          "mediaType": "document"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "drive_download_1" },
    { "source": "drive_download_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: 1. Sistema usa refreshToken automaticamente se accessToken expirou 2. Arquivo é baixado e enviado via WhatsApp

fileId (string, obrigatório)

O que é: ID único do arquivo no Google Drive que será baixado.

Como obter: Via URL do arquivo, drive_list, drive_search ou após drive_upload.

Flow completo para testar:

{
  "name": "Teste Drive Download - FileId Dinâmico",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Solicitar ID",
        "parameters": {
          "message": "Escolha o documento:\n\n1️⃣ Contrato Padrão\n2️⃣ Proposta Comercial\n3️⃣ Termos de Uso"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Receber Escolha",
        "parameters": {
          "message": "Digite o número:",
          "variableName": "escolha"
        }
      }
    },
    {
      "id": "switch_1",
      "type": "switch",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Definir FileId",
        "parameters": {
          "variable": "{{escolha}}",
          "cases": [
            { "value": "1", "target": "variable_contrato" },
            { "value": "2", "target": "variable_proposta" },
            { "value": "3", "target": "variable_termos" }
          ]
        }
      }
    },
    {
      "id": "variable_contrato",
      "type": "variable",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "ID Contrato",
        "parameters": {
          "variableName": "fileId",
          "value": "1ContratoFileID123"
        }
      }
    },
    {
      "id": "variable_proposta",
      "type": "variable",
      "position": { "x": 900, "y": 130 },
      "data": {
        "label": "ID Proposta",
        "parameters": {
          "variableName": "fileId",
          "value": "1PropostaFileID456"
        }
      }
    },
    {
      "id": "variable_termos",
      "type": "variable",
      "position": { "x": 900, "y": 210 },
      "data": {
        "label": "ID Termos",
        "parameters": {
          "variableName": "fileId",
          "value": "1TermosFileID789"
        }
      }
    },
    {
      "id": "drive_download_1",
      "type": "google_drive",
      "position": { "x": 1100, "y": 130 },
      "data": {
        "label": "Baixar Documento",
        "parameters": {
          "operation": "download",
          "accessToken": "{{system.googleAccessToken}}",
          "refreshToken": "{{system.googleRefreshToken}}",
          "fileId": "{{fileId}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1300, "y": 130 },
      "data": {
        "label": "Enviar",
        "parameters": {
          "message": "Aqui está o documento solicitado:",
          "mediaBase64": "{{drive_download_1.content}}",
          "mediaType": "document"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1500, "y": 130 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "switch_1" },
    { "source": "switch_1", "target": "variable_contrato", "label": "1" },
    { "source": "switch_1", "target": "variable_proposta", "label": "2" },
    { "source": "switch_1", "target": "variable_termos", "label": "3" },
    { "source": "variable_contrato", "target": "drive_download_1" },
    { "source": "variable_proposta", "target": "drive_download_1" },
    { "source": "variable_termos", "target": "drive_download_1" },
    { "source": "drive_download_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Teste: 1. Digite: "1" 2. Sistema baixa arquivo do fileId específico 3. Documento é enviado via WhatsApp

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Deve ser "download"
accessToken string Sim Token OAuth2 do Google
refreshToken string Sim Token para renovar acesso
fileId string Sim ID do arquivo no Drive

Exemplo 1: Enviar Contrato Padrão

Objetivo: Cliente solicita contrato e recebe automaticamente via WhatsApp.

JSON para Importar

{
  "name": "Envio Automático de Contrato",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Menu",
        "parameters": {
          "message": "Olá! Como posso ajudar?\n\n1️⃣ Solicitar Contrato\n2️⃣ Falar com Atendente"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Receber Opção",
        "parameters": {
          "message": "Digite o número da opção:",
          "variableName": "opcao",
          "timeout": 60000
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Verificar Opção",
        "parameters": {
          "variable": "{{opcao}}",
          "operator": "equals",
          "value": "1"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Processar",
        "parameters": {
          "message": "Aguarde um momento, estou preparando seu contrato..."
        }
      }
    },
    {
      "id": "drive_download_1",
      "type": "google_drive",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Baixar Contrato",
        "parameters": {
          "operation": "download",
          "accessToken": "{{system.googleAccessToken}}",
          "refreshToken": "{{system.googleRefreshToken}}",
          "fileId": "1ContratoTemplateID123456789"
        }
      }
    },
    {
      "id": "message_3",
      "type": "message",
      "position": { "x": 1300, "y": 50 },
      "data": {
        "label": "Enviar Contrato",
        "parameters": {
          "message": "Aqui está seu contrato padrão:\n\n📄 Contrato de Prestação de Serviços\n\nPor favor, leia com atenção e nos retorne assinado.",
          "mediaBase64": "{{drive_download_1.content}}",
          "mediaType": "document",
          "mediaFilename": "contrato_{{contact.name}}.pdf"
        }
      }
    },
    {
      "id": "message_4",
      "type": "message",
      "position": { "x": 1500, "y": 50 },
      "data": {
        "label": "Próximos Passos",
        "parameters": {
          "message": "Após ler o contrato, você pode:\n\n✍️ Assinar e retornar\n📞 Tirar dúvidas conosco\n\nQualquer dúvida, estou à disposição!"
        }
      }
    },
    {
      "id": "message_5",
      "type": "message",
      "position": { "x": 900, "y": 150 },
      "data": {
        "label": "Encaminhar",
        "parameters": {
          "message": "Aguarde, estou te conectando com um atendente..."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_2", "label": "true" },
    { "source": "condition_1", "target": "message_5", "label": "false" },
    { "source": "message_2", "target": "drive_download_1" },
    { "source": "drive_download_1", "target": "message_3" },
    { "source": "message_3", "target": "message_4" },
    { "source": "message_4", "target": "end_1" },
    { "source": "message_5", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Olá! Como posso ajudar?

1️⃣ Solicitar Contrato
2️⃣ Falar com Atendente

Sistema: Digite o número da opção:
Usuário: 1

Sistema: Aguarde um momento, estou preparando seu contrato...

Sistema: Aqui está seu contrato padrão:

📄 Contrato de Prestação de Serviços

Por favor, leia com atenção e nos retorne assinado.
[Arquivo: contrato_Jose_Roberto.pdf enviado]

Sistema: Após ler o contrato, você pode:

✍️ Assinar e retornar
📞 Tirar dúvidas conosco

Qualquer dúvida, estou à disposição!

Exemplo 2: Processar Planilha de Dados

Objetivo: Baixar planilha Excel do Drive, extrair dados e processar informações.

JSON para Importar

{
  "name": "Processamento de Planilha Excel",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "schedule_1",
      "type": "schedule",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Diário 8h",
        "parameters": {
          "cron": "0 8 * * *",
          "timezone": "America/Sao_Paulo"
        }
      }
    },
    {
      "id": "drive_download_1",
      "type": "google_drive",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Baixar Planilha",
        "parameters": {
          "operation": "download",
          "accessToken": "{{system.googleAccessToken}}",
          "refreshToken": "{{system.googleRefreshToken}}",
          "fileId": "1PlanilhaVendasID123"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Converter Base64",
        "parameters": {
          "variableName": "excelData",
          "value": "{{base64Decode(drive_download_1.content)}}"
        }
      }
    },
    {
      "id": "variable_2",
      "type": "variable",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Processar Excel",
        "parameters": {
          "variableName": "dadosProcessados",
          "value": "{{parseExcel(excelData)}}"
        }
      }
    },
    {
      "id": "loop_1",
      "type": "loop",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Para Cada Linha",
        "parameters": {
          "array": "{{dadosProcessados.rows}}",
          "itemVariable": "linha"
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Venda > 1000?",
        "parameters": {
          "variable": "{{linha.valor}}",
          "operator": "greaterThan",
          "value": 1000
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1500, "y": 50 },
      "data": {
        "label": "Notificar Gerente",
        "parameters": {
          "message": "🎯 Venda Grande!\n\nVendedor: {{linha.vendedor}}\nCliente: {{linha.cliente}}\nValor: R$ {{linha.valor}}\n\nParabéns!",
          "to": "{{gerente.phone}}"
        }
      }
    },
    {
      "id": "accumulator_1",
      "type": "accumulator",
      "position": { "x": 1500, "y": 150 },
      "data": {
        "label": "Somar Total",
        "parameters": {
          "variableName": "totalVendas",
          "operation": "sum",
          "value": "{{linha.valor}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1700, "y": 100 },
      "data": {
        "label": "Relatório Final",
        "parameters": {
          "message": "📊 Relatório de Vendas Processado\n\nTotal de vendas: R$ {{totalVendas}}\nLinhas processadas: {{length(dadosProcessados.rows)}}\n\nDados atualizados!",
          "to": "{{admin.phone}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "schedule_1" },
    { "source": "schedule_1", "target": "drive_download_1" },
    { "source": "drive_download_1", "target": "variable_1" },
    { "source": "variable_1", "target": "variable_2" },
    { "source": "variable_2", "target": "loop_1" },
    { "source": "loop_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_1", "label": "true" },
    { "source": "condition_1", "target": "accumulator_1", "label": "always" },
    { "source": "message_1", "target": "accumulator_1" },
    { "source": "accumulator_1", "target": "loop_1", "label": "continue" },
    { "source": "loop_1", "target": "message_2", "label": "done" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

[Execução automática às 8h]

Sistema: [WhatsApp para gerente - para cada venda > 1000]
🎯 Venda Grande!

Vendedor: Maria Silva
Cliente: Empresa XYZ
Valor: R$ 1.500

Parabéns!

---

Sistema: [WhatsApp para admin ao final]
📊 Relatório de Vendas Processado

Total de vendas: R$ 45.230
Linhas processadas: 156

Dados atualizados!

Resposta do Node

{
  "success": true,
  "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQg..."
}

Campos retornados:

  • success: true se download foi bem-sucedido
  • content: Conteúdo do arquivo em base64

Boas Práticas

SIM:

  • Verifique se tem permissão de leitura no arquivo antes
  • Armazene fileId em variáveis/banco para reutilização
  • Use em conjunto com drive_list ou drive_search para localizar arquivos
  • Implemente timeout adequado para arquivos grandes
  • Valide o conteúdo após download
  • Use retry em caso de falha de rede

NÃO:

  • Não tente baixar arquivos muito grandes (>50MB) sem controle
  • Não use fileId hardcoded (use variáveis dinâmicas)
  • Não ignore erros de permissão
  • Não exponha conteúdo sensível em logs
  • Não faça downloads desnecessários (cache quando possível)

Dicas

💡 Dica 1: Para arquivos do Google Docs/Sheets/Slides, use drive_export ao invés de download para converter para formatos comuns (PDF, Excel, etc).

💡 Dica 2: Combine com drive_get_metadata para verificar tamanho do arquivo antes de baixar.

💡 Dica 3: Use webContentLink se precisar apenas de um link de download (mais leve que baixar o arquivo).

💡 Dica 4: Para processar arquivos, decodifique o base64: Buffer.from(content, 'base64').

💡 Dica 5: Armazene arquivos baixados em cache temporário se for usar múltiplas vezes no flow.

Próximo Node

DRIVE_UPLOAD - Upload de arquivos no Google Drive → DRIVE_LIST - Listar arquivos e pastas → DRIVE_EXPORT - Exportar Google Docs para outros formatos