Pular para conteúdo

AWS S3 UPLOAD - Enviar Arquivo para S3

O que é este Node?

O AWS S3 UPLOAD é o node responsável por fazer upload de arquivos para buckets do Amazon S3 com controle de permissões (ACL), tipo de conteúdo e metadados.

Por que este Node existe?

Armazenar arquivos no S3 é uma necessidade comum em automações. O S3 UPLOAD existe para:

  1. Armazenamento em nuvem: Salvar arquivos, imagens, documentos em buckets S3
  2. Distribuição de conteúdo: Hospedar arquivos acessíveis via URL pública ou privada
  3. Backup automatizado: Fazer backup de dados gerados pelo flow
  4. Integração com outros serviços: S3 é amplamente usado por outros serviços AWS

Como funciona internamente?

Quando o S3 UPLOAD é executado, o sistema:

  1. Recebe as credenciais AWS: Access Key ID, Secret Access Key e região
  2. Valida o bucket de destino: Verifica se o bucketName foi informado
  3. Prepara o arquivo: Converte o conteúdo de base64 para Buffer
  4. Define metadados: ContentType e ACL (permissões)
  5. Faz o upload: Envia para o bucket S3 especificado
  6. Retorna a localização: URL pública (se ACL permitir) ou chave do objeto

Código interno (aws-executors.service.ts:22-35):

case 'upload':
  const uploadResult = await s3.upload({
    Bucket: data.bucketName,
    Key: data.key,
    Body: Buffer.from(data.content, 'base64'),
    ContentType: data.contentType,
    ACL: data.acl || 'private',
  }).promise();
  return {
    success: true,
    location: uploadResult.Location,
    key: uploadResult.Key,
    bucket: uploadResult.Bucket,
  };

Quando você DEVE usar este Node?

Use S3 UPLOAD sempre que precisar armazenar arquivos na nuvem AWS:

Casos de uso

  1. Upload de documentos do usuário: "Envie seu RG" → salvar no S3
  2. Armazenar imagens processadas: Depois de processar uma imagem com IA
  3. Backup de relatórios gerados: Salvar PDFs gerados automaticamente
  4. Armazenar logs ou dados JSON: Para análise posterior
  5. Hospedar arquivos para compartilhamento: Gerar URL pública

Quando NÃO usar S3 UPLOAD

  • Arquivos pequenos temporários: Use variáveis se for só para o flow
  • Banco de dados relacional: Use DynamoDB ou RDS para dados estruturados
  • Tempo real: S3 não é ideal para streaming (use S3 + CloudFront)

Parâmetros Detalhados

accessKeyId (string, obrigatório)

O que é: Sua AWS Access Key ID (credencial de autenticação).

Onde conseguir: IAM Console → Users → Security credentials → Create access key

Flow completo para testar:

{
  "name": "Teste S3 Upload - Access Key",
  "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": "Preparar Arquivo",
        "parameters": {
          "variable": "arquivo_base64",
          "value": "SGVsbG8gV29ybGQh"
        }
      }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload S3",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
          "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
          "region": "us-east-1",
          "bucketName": "meu-bucket",
          "key": "teste/hello.txt",
          "content": "{{arquivo_base64}}",
          "contentType": "text/plain"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Arquivo enviado! URL: {{s3_location}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Substitua pelos seus dados reais da AWS. O arquivo será enviado para o bucket.

secretAccessKey (string, obrigatório)

O que é: Sua AWS Secret Access Key (senha da credencial).

Segurança: NUNCA exponha essa chave! Use variáveis de ambiente ou AWS Secrets Manager.

Padrão: Não tem padrão - SEMPRE obrigatória

region (string, obrigatório)

O que é: Região AWS onde está o bucket S3.

Valores comuns: - us-east-1 (Norte da Virgínia) - us-west-2 (Oregon) - sa-east-1 (São Paulo) - eu-west-1 (Irlanda)

Flow completo para testar:

{
  "name": "Teste S3 Upload - Região São Paulo",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload Brasil",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "sa-east-1",
          "bucketName": "bucket-brasil",
          "key": "uploads/documento.pdf",
          "content": "base64_do_arquivo",
          "contentType": "application/pdf"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "Arquivo salvo na região São Paulo (sa-east-1)"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

bucketName (string, obrigatório)

O que é: Nome do bucket S3 onde o arquivo será salvo.

Importante: O bucket deve existir previamente. Crie no AWS Console.

Flow completo para testar:

{
  "name": "Teste S3 Upload - Bucket Name",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "uploads-producao",
          "key": "documentos/arquivo.txt",
          "content": "SGVsbG8h",
          "contentType": "text/plain"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 500, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "s3_1" },
    { "source": "s3_1", "target": "end_1" }
  ]
}

key (string, obrigatório)

O que é: Caminho completo do arquivo dentro do bucket (como se fosse um "nome de arquivo").

Formato: pasta1/pasta2/nome-arquivo.extensao

Exemplos: - uploads/2025/01/documento.pdf - imagens/perfil/usuario-123.jpg - backup/relatorio-2025-01-15.json

Flow completo para testar:

{
  "name": "Teste S3 Upload - Key com Data",
  "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": "Gerar Nome",
        "parameters": {
          "variable": "data_atual",
          "value": "2025-01-15"
        }
      }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Upload Organizado",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "meu-bucket",
          "key": "uploads/{{data_atual}}/arquivo.txt",
          "content": "Q29udGXDumRvIGRvIGFycXVpdm8=",
          "contentType": "text/plain"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Salvo em: uploads/{{data_atual}}/arquivo.txt"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

content (string base64, obrigatório)

O que é: Conteúdo do arquivo em formato Base64.

Como converter: Use btoa() no JavaScript ou bibliotecas de encoding.

Exemplo: "SGVsbG8gV29ybGQh" = "Hello World!"

Flow completo para testar:

{
  "name": "Teste S3 Upload - Content Base64",
  "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 Texto",
        "parameters": {
          "message": "Digite o texto do arquivo:",
          "variable": "texto_usuario"
        }
      }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Salvar no S3",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "meu-bucket",
          "key": "textos/usuario.txt",
          "content": "{{texto_usuario}}",
          "contentType": "text/plain"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "Texto salvo no S3!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

contentType (string, obrigatório)

O que é: Tipo MIME do arquivo (diz ao navegador como interpretar).

Valores comuns: - text/plain - Arquivo de texto - application/pdf - PDF - image/jpeg - Imagem JPG - image/png - Imagem PNG - application/json - JSON - video/mp4 - Vídeo MP4

Flow completo para testar:

{
  "name": "Teste S3 Upload - Content Type PDF",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload PDF",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "documentos",
          "key": "pdfs/relatorio.pdf",
          "content": "base64_do_pdf",
          "contentType": "application/pdf"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "PDF enviado! Tipo: application/pdf"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

acl (string, opcional)

O que é: Controle de acesso (Access Control List) do arquivo.

Padrão: "private" (apenas você com credenciais pode acessar)

Opções: - private - Privado (padrão) - public-read - Leitura pública (qualquer um pode baixar) - public-read-write - Leitura e escrita pública (CUIDADO!) - authenticated-read - Apenas usuários AWS autenticados

Flow completo para testar:

{
  "name": "Teste S3 Upload - ACL Public",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Upload Público",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "imagens-publicas",
          "key": "fotos/foto-perfil.jpg",
          "content": "base64_da_imagem",
          "contentType": "image/jpeg",
          "acl": "public-read"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "URL Pública",
        "parameters": {
          "message": "Imagem pública disponível em: {{s3_location}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Com acl: "public-read", a URL retornada será acessível sem autenticação.

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Deve ser "upload"
accessKeyId string Sim AWS Access Key ID
secretAccessKey string Sim AWS Secret Access Key
region string Sim Região AWS (ex: us-east-1)
bucketName string Sim Nome do bucket S3
key string Sim Caminho do arquivo no bucket
content string Sim Conteúdo em Base64
contentType string Sim Tipo MIME do arquivo
acl string Não Permissões (padrão: private)

Exemplo 1: Upload de Documento do Usuário

Objetivo: Receber um documento (RG/CPF) do usuário e salvar no S3.

JSON para Importar

{
  "name": "Upload Documento - RG do Usuário",
  "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 RG",
        "parameters": {
          "message": "Por favor, envie uma foto do seu RG"
        }
      }
    },
    {
      "id": "media_1",
      "type": "media",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Receber Foto",
        "parameters": {
          "message": "Aguardando foto do RG...",
          "variable": "foto_rg_base64",
          "mediaType": "image"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Gerar Nome Arquivo",
        "parameters": {
          "variable": "nome_arquivo",
          "value": "documentos/{{phone}}/rg.jpg"
        }
      }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Salvar no S3",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
          "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
          "region": "sa-east-1",
          "bucketName": "documentos-clientes",
          "key": "{{nome_arquivo}}",
          "content": "{{foto_rg_base64}}",
          "contentType": "image/jpeg",
          "acl": "private"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "RG recebido e armazenado com sucesso! Obrigado."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "media_1" },
    { "source": "media_1", "target": "variable_1" },
    { "source": "variable_1", "target": "s3_1" },
    { "source": "s3_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Por favor, envie uma foto do seu RG
Usuário: [envia foto]
Sistema: Aguardando foto do RG...
Sistema: RG recebido e armazenado com sucesso! Obrigado.

Exemplo 2: Backup de Relatório JSON

Objetivo: Gerar um relatório em JSON e fazer backup no S3.

JSON para Importar

{
  "name": "Backup Relatório JSON no S3",
  "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": "Criar Relatório",
        "parameters": {
          "variable": "relatorio",
          "value": "{\"data\":\"2025-01-15\",\"vendas\":150,\"receita\":7500}"
        }
      }
    },
    {
      "id": "variable_2",
      "type": "variable",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Converter Base64",
        "parameters": {
          "variable": "relatorio_base64",
          "value": "eyJkYXRhIjoiMjAyNS0wMS0xNSIsInZlbmRhcyI6MTUwLCJyZWNlaXRhIjo3NTAwfQ=="
        }
      }
    },
    {
      "id": "s3_1",
      "type": "aws_s3",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Backup S3",
        "parameters": {
          "operation": "upload",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "bucketName": "backups-relatorios",
          "key": "relatorios/2025/01/relatorio-2025-01-15.json",
          "content": "{{relatorio_base64}}",
          "contentType": "application/json",
          "acl": "private"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Backup realizado! Arquivo: {{s3_key}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "variable_2" },
    { "source": "variable_2", "target": "s3_1" },
    { "source": "s3_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Backup realizado! Arquivo: relatorios/2025/01/relatorio-2025-01-15.json

Resposta do Node

{
  "success": true,
  "location": "https://meu-bucket.s3.us-east-1.amazonaws.com/uploads/arquivo.txt",
  "key": "uploads/arquivo.txt",
  "bucket": "meu-bucket"
}

Variáveis criadas: - {{s3_location}} - URL completa do arquivo - {{s3_key}} - Caminho do arquivo (key) - {{s3_bucket}} - Nome do bucket

Configuração AWS

1. Criar Access Key

  1. Acesse AWS Console → IAM
  2. Clique em "Users" → Selecione seu usuário
  3. Aba "Security credentials"
  4. Clique "Create access key"
  5. Salve Access Key ID e Secret Access Key

2. Criar Bucket S3

  1. Acesse AWS Console → S3
  2. Clique "Create bucket"
  3. Escolha nome único (ex: minha-empresa-uploads)
  4. Selecione região (ex: sa-east-1 para São Paulo)
  5. Configure permissões (Block public access se for privado)

3. Permissões IAM

Sua Access Key precisa dessas permissões:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::seu-bucket/*"
    }
  ]
}

Boas Práticas

Segurança

SIM: - Use IAM roles com permissões mínimas (apenas PutObject) - NUNCA exponha Access Keys no código (use variáveis de ambiente) - Use ACL private para dados sensíveis - Ative versionamento no bucket para recuperação - Configure lifecycle policies para deletar arquivos antigos

NÃO: - Nunca use ACL public-read-write (qualquer um pode modificar!) - Não use mesma Access Key para tudo (crie específica para S3) - Não armazene credenciais em variáveis do flow visíveis

Performance

SIM: - Organize arquivos em pastas lógicas (uploads/2025/01/) - Use ContentType correto (ajuda navegadores e CloudFront) - Considere usar S3 Transfer Acceleration para uploads grandes - Para muitos uploads, use S3 Batch Operations

NÃO: - Não coloque milhares de arquivos na raiz do bucket - Não faça upload de arquivos gigantes (> 100MB) sem multipart - Não use nomes de arquivo com caracteres especiais

Organização

SIM: - Use padrão de nomes: categoria/ano/mes/arquivo.ext - Inclua timestamp ou ID único no nome - Agrupe por cliente/usuário: uploads/cliente-123/documento.pdf

Exemplos de keys bem estruturadas: - documentos/2025/01/15/cliente-456-rg.jpg - imagens/perfil/usuario-789.png - backups/relatorios/2025-01-15-vendas.json

Dicas

Custo: S3 cobra por GB armazenado + transferências. Use S3 Intelligent-Tiering para economizar.

Recuperação: Ative versionamento no bucket para recuperar arquivos deletados acidentalmente.

CDN: Para servir arquivos públicos rapidamente, use CloudFront + S3.

Logs: Configure S3 Server Access Logging para auditar acessos.

Criptografia: Ative SSE-S3 ou SSE-KMS para criptografar dados em repouso.

Próximo Node

S3 DOWNLOAD - Baixar arquivo do S3 → S3 DELETE - Deletar arquivo do S3 → S3 LIST - Listar objetos no bucket