Pular para conteúdo

FTP_UPLOAD - Enviar Arquivo para Servidor FTP

O que é este Node?

O FTP_UPLOAD é o node responsável por enviar arquivos do sistema local para um servidor FTP remoto. Faz parte do conjunto de operações FTP para transferência de arquivos.

Por que este Node existe?

Transferir arquivos para servidores remotos é uma necessidade comum em automações empresariais. O FTP_UPLOAD existe para:

  1. Distribuir Documentos: Enviar relatórios, contratos e documentos gerados para servidores de parceiros
  2. Publicar Arquivos: Fazer upload de imagens, vídeos e assets para servidores de hospedagem
  3. Backup Automatizado: Enviar backups de dados para servidores FTP externos
  4. Integração B2B: Trocar arquivos com parceiros que usam FTP como canal de integração

Como funciona internamente?

Quando o FTP_UPLOAD é executado, o sistema:

  1. Valida Arquivo Local: Verifica se o arquivo especificado existe no sistema
  2. Conecta ao FTP: Estabelece conexão com servidor usando credenciais fornecidas
  3. Prepara Transfer: Cria streams de leitura do arquivo local
  4. Envia Arquivo: Transfere bytes do arquivo local para caminho remoto especificado
  5. Registra Tamanho: Captura tamanho do arquivo enviado para confirmação
  6. Se falhar: Retorna erro detalhando problema (arquivo não encontrado, sem permissão, etc)
  7. Se sucesso: Confirma upload com timestamp e detalhes do arquivo

Código interno (ftp-executor.service.ts:284-304):

private async uploadFile(client: FTP.Client, data: FTPNodeData): Promise<any> {
  const localPath = data.localFilePath!;
  const remotePath = data.remoteFilePath!;

  // Check if local file exists
  if (!fs.existsSync(localPath)) {
    throw new Error(`Local file not found: ${localPath}`);
  }

  this.logger.debug(`Uploading file: ${localPath}${remotePath}`);

  await client.uploadFrom(localPath, remotePath);

  return {
    success: true,
    localPath,
    remotePath,
    size: fs.statSync(localPath).size,
    uploadedAt: new Date().toISOString()
  };
}

Quando você DEVE usar este Node?

Use FTP_UPLOAD sempre que precisar de enviar arquivos para servidor FTP remoto:

Casos de uso

  1. Relatórios Diários: "Enviar relatório de vendas gerado às 18h para servidor FTP do cliente"
  2. Upload de Mídias: "Fazer upload de imagens de produtos para servidor de e-commerce via FTP"
  3. Backup de Dados: "Enviar backup do banco de dados para servidor FTP externo todas as noites"

Quando NÃO usar FTP_UPLOAD

  • APIs Disponíveis: Use endpoints REST se a aplicação oferecer API moderna
  • Cloud Storage: Use nodes S3, Google Drive ou Dropbox para armazenamento em nuvem
  • Transferências Seguras: Use SFTP_UPLOAD para dados sensíveis (mais seguro que FTP)

Parâmetros Detalhados

localFilePath (string, obrigatório)

O que é: Caminho completo do arquivo no sistema local que será enviado.

Padrão: Nenhum (obrigatório)

Flow completo para testar:

{
  "name": "Teste FTP Upload - LocalPath",
  "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": "Definir Arquivo Local",
        "parameters": {
          "variableName": "local_file",
          "value": "/tmp/relatorio_vendas.pdf"
        }
      }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload Arquivo",
        "parameters": {
          "host": "ftp.example.com",
          "username": "user",
          "password": "pass123",
          "operation": "upload",
          "localFilePath": "{{local_file}}",
          "remoteFilePath": "/uploads/relatorio.pdf",
          "outputVariable": "upload_result"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Arquivo enviado: {{upload_result.size}} bytes"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: O arquivo deve existir no caminho especificado antes do upload.

remoteFilePath (string, obrigatório)

O que é: Caminho completo onde o arquivo será salvo no servidor FTP remoto.

Padrão: Nenhum (obrigatório)

Flow completo para testar:

{
  "name": "Teste FTP Upload - RemotePath",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Pedir Caminho Remoto",
        "parameters": {
          "message": "Para qual pasta enviar? (Ex: /uploads/2025/)",
          "variableName": "remote_folder"
        }
      }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload com Path Dinâmico",
        "parameters": {
          "host": "ftp.example.com",
          "username": "user",
          "password": "pass",
          "operation": "upload",
          "localFilePath": "/tmp/documento.pdf",
          "remoteFilePath": "{{remote_folder}}/documento.pdf"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Arquivo enviado para: {{remote_folder}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Digite "/uploads/2025/". Sistema enviará arquivo para esta pasta remota.

outputVariable (string, opcional)

O que é: Nome da variável onde resultado do upload será armazenado.

Padrão: "ftp_result"

Flow completo para testar:

{
  "name": "Teste FTP Upload - OutputVariable",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload com Variável Customizada",
        "parameters": {
          "host": "ftp.example.com",
          "username": "user",
          "password": "pass",
          "operation": "upload",
          "localFilePath": "/tmp/relatorio.pdf",
          "remoteFilePath": "/reports/relatorio.pdf",
          "outputVariable": "upload_details"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Detalhes",
        "parameters": {
          "message": "Upload concluído!\nTamanho: {{upload_details.size}} bytes\nHora: {{upload_details.uploadedAt}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Resultado fica disponível em {{upload_details}} para usar em nodes posteriores.

Parâmetros

Campo Tipo Obrigatório Descrição
host string Sim Endereço do servidor FTP
port number Não Porta TCP (padrão: 21)
username string Sim Nome de usuário
password string Sim Senha
secure boolean Não FTPS - SSL/TLS (padrão: false)
operation string Sim Deve ser "upload"
localFilePath string Sim Caminho do arquivo local a enviar
remoteFilePath string Sim Caminho destino no servidor remoto
outputVariable string Não Variável de resultado (padrão: ftp_result)

Exemplo 1: Upload de Relatório Diário Automatizado

Objetivo: Enviar relatório PDF gerado automaticamente para servidor FTP do cliente

JSON para Importar

{
  "name": "Upload Relatório Diário",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início (18h diariamente)" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Preparar Caminhos",
        "parameters": {
          "variableName": "data_hoje",
          "value": "2025-01-15"
        }
      }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload Relatório",
        "parameters": {
          "host": "ftp.cliente.com",
          "port": 21,
          "username": "empresa_reports",
          "password": "secret123",
          "secure": false,
          "operation": "upload",
          "localFilePath": "/var/reports/vendas_{{data_hoje}}.pdf",
          "remoteFilePath": "/incoming/vendas_{{data_hoje}}.pdf",
          "outputVariable": "upload_info"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Notificar Sucesso",
        "parameters": {
          "message": "✅ Relatório enviado!\nTamanho: {{upload_info.size}} bytes\nData: {{data_hoje}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: ✅ Relatório enviado!
Tamanho: 524288 bytes
Data: 2025-01-15

Exemplo 2: Upload de Múltiplas Imagens com Confirmação

Objetivo: Enviar várias imagens de produtos para servidor FTP e confirmar cada uma

JSON para Importar

{
  "name": "Upload Múltiplas Imagens",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload Imagem 1",
        "parameters": {
          "host": "ftp.loja.com",
          "username": "produtos",
          "password": "pass123",
          "operation": "upload",
          "localFilePath": "/tmp/produto_001.jpg",
          "remoteFilePath": "/images/produtos/produto_001.jpg",
          "outputVariable": "img1"
        }
      }
    },
    {
      "id": "ftp_2",
      "type": "ftp",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload Imagem 2",
        "parameters": {
          "host": "ftp.loja.com",
          "username": "produtos",
          "password": "pass123",
          "operation": "upload",
          "localFilePath": "/tmp/produto_002.jpg",
          "remoteFilePath": "/images/produtos/produto_002.jpg",
          "outputVariable": "img2"
        }
      }
    },
    {
      "id": "ftp_3",
      "type": "ftp",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Upload Imagem 3",
        "parameters": {
          "host": "ftp.loja.com",
          "username": "produtos",
          "password": "pass123",
          "operation": "upload",
          "localFilePath": "/tmp/produto_003.jpg",
          "remoteFilePath": "/images/produtos/produto_003.jpg",
          "outputVariable": "img3"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Resumo Final",
        "parameters": {
          "message": "📤 3 imagens enviadas:\n✅ {{img1.remotePath}}\n✅ {{img2.remotePath}}\n✅ {{img3.remotePath}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "ftp_2" },
    { "source": "ftp_2", "target": "ftp_3" },
    { "source": "ftp_3", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: 📤 3 imagens enviadas:
✅ /images/produtos/produto_001.jpg
✅ /images/produtos/produto_002.jpg
✅ /images/produtos/produto_003.jpg

Exemplo 3: Upload com Validação de Arquivo Local

Objetivo: Verificar existência do arquivo antes de tentar upload

JSON para Importar

{
  "name": "Upload com Validação",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Pedir Caminho do Arquivo",
        "parameters": {
          "message": "Digite o caminho completo do arquivo:",
          "variableName": "arquivo_local"
        }
      }
    },
    {
      "id": "ftp_1",
      "type": "ftp",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Tentar Upload",
        "parameters": {
          "host": "ftp.backup.com",
          "port": 21,
          "username": "backup_user",
          "password": "secure_pass",
          "secure": true,
          "operation": "upload",
          "localFilePath": "{{arquivo_local}}",
          "remoteFilePath": "/backups/{{arquivo_local}}",
          "outputVariable": "resultado_upload"
        }
      }
    },
    {
      "id": "message_success",
      "type": "message",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "✅ Arquivo enviado com sucesso!\nTamanho: {{resultado_upload.size}} bytes"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "ftp_1" },
    { "source": "ftp_1", "target": "message_success" },
    { "source": "message_success", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o caminho completo do arquivo:
Usuário: /tmp/backup_database.sql
Sistema: ✅ Arquivo enviado com sucesso!
Tamanho: 2048576 bytes

Resposta do Node

{
  "success": true,
  "data": {
    "ftp_result": {
      "success": true,
      "localPath": "/tmp/relatorio.pdf",
      "remotePath": "/uploads/relatorio.pdf",
      "size": 524288,
      "uploadedAt": "2025-01-15T18:30:00.000Z"
    },
    "operation": "upload",
    "host": "ftp.example.com",
    "timestamp": "2025-01-15T18:30:00.000Z"
  },
  "executionTime": 2345,
  "logs": [
    "Uploaded file: /tmp/relatorio.pdf → /uploads/relatorio.pdf"
  ]
}

Boas Práticas

SIM:

  • Valide existência do arquivo local antes do upload
  • Use caminhos absolutos para maior confiabilidade
  • Organize arquivos remotos em pastas com estrutura lógica (ex: /uploads/2025/01/)
  • Inclua data/timestamp no nome do arquivo para versionamento
  • Use FTPS (secure: true) para upload de dados sensíveis

NÃO:

  • Não tente fazer upload de arquivos que não existem localmente
  • Não use caminhos relativos que dependem do diretório de execução
  • Não sobrescreva arquivos importantes sem backup
  • Não faça upload de arquivos gigantes sem considerar timeout
  • Não ignore erros de upload - sempre trate falhas adequadamente

Dicas

💡 Dica 1: Velocidade do upload depende da sua conexão de internet. Arquivos grandes podem levar minutos.

💡 Dica 2: Se upload falhar, verifique: (1) arquivo existe localmente, (2) você tem permissão de escrita no servidor remoto, (3) caminho remoto está correto.

💡 Dica 3: Para upload de múltiplos arquivos, considere usar node LOOP para iterar sobre lista de arquivos.

💡 Dica 4: FTP transfere arquivos em modo binário ou texto. Para PDFs, imagens e executáveis, modo binário é automático.

Próximos Nodes

FTP_DOWNLOAD - Baixar arquivo do servidor FTP → FTP_LIST - Listar arquivos antes de fazer upload → FTP_DELETE - Apagar arquivo antigo após upload de nova versão → FTP_MKDIR - Criar diretório antes de fazer upload