SQS SEND - Enviar Mensagem para Fila
O que é este Node?
O SQS SEND é o node responsável por enviar mensagens para filas do AWS SQS (Simple Queue Service) de forma assíncrona e confiável.
Por que este Node existe?
Processar tarefas de forma assíncrona é essencial em sistemas escaláveis. O SQS SEND existe para:
- Desacoplamento: Separar produtores de consumidores de mensagens
- Processamento assíncrono: Enviar tarefas para serem processadas posteriormente
- Escalabilidade: Distribuir carga entre múltiplos consumidores
- Resiliência: Garantir que mensagens não sejam perdidas mesmo em falhas
- Controle de taxa: Processar mensagens no ritmo adequado
- Persistência: Armazenar mensagens até serem processadas
Como funciona internamente?
Quando o SQS SEND é executado, o sistema:
- Recebe os parâmetros: URL da fila, corpo da mensagem, atributos
- Autentica na AWS: Usa accessKeyId, secretAccessKey e region
- Serializa mensagem: Converte messageBody para JSON
- Envia para fila: Publica mensagem no SQS via SDK AWS
- Aplica delay: Se definido, atrasa entrega da mensagem
- Retorna MessageId: ID único da mensagem enviada
- Se erro: Lança exceção com detalhes do erro
Código interno (aws-executors.service.ts:104-115):
case 'sendMessage':
const sendResult = await sqs.sendMessage({
QueueUrl: data.queueUrl,
MessageBody: JSON.stringify(data.messageBody),
MessageAttributes: data.messageAttributes,
DelaySeconds: data.delaySeconds,
}).promise();
return {
success: true,
messageId: sendResult.MessageId,
};
Quando você DEVE usar este Node?
Use SQS SEND sempre que precisar de processamento assíncrono e desacoplado:
Casos de uso:
- Processamento de imagens: Enviar imagens para resize assíncrono
- Envio de emails: Encaminhar emails para processamento em lote
- Integração de sistemas: Comunicar entre microserviços
- Processamento de pedidos: Enviar pedidos para fulfillment
- Logs e auditoria: Enviar eventos para processamento posterior
- Tarefas agendadas: Agendar execução de jobs
- Importação de dados: Processar grandes volumes em background
Quando NÃO usar SQS SEND:
- Respostas síncronas: Use Lambda direto se precisa resposta imediata
- Pub/Sub multi-destino: Use SNS para broadcast para múltiplos assinantes
- Processamento em tempo real: Use Kinesis para streaming
Diferença: SQS vs SNS
SQS (Queue - Fila)
- Modelo: Ponto a ponto (1 produtor → 1 consumidor)
- Uso: Processar mensagens sequencialmente
- Garantia: Cada mensagem processada uma vez
- Exemplo: Fila de processamento de pedidos
SNS (Topic - Pub/Sub)
- Modelo: Broadcast (1 produtor → N assinantes)
- Uso: Notificar múltiplos sistemas
- Garantia: Todos assinantes recebem a mensagem
- Exemplo: Notificar webhook + email + SMS
Tipos de Filas SQS
Standard Queue (Padrão)
- Throughput: Ilimitado
- Ordem: Melhor esforço (pode desordenar)
- Duplicatas: Pode entregar mais de uma vez
- Latência: Milissegundos
- Uso: Máxima performance
FIFO Queue
- Throughput: 300 msgs/seg (3000 com batching)
- Ordem: Garantida (First In, First Out)
- Duplicatas: Exatamente uma entrega
- Latência: Ligeiramente maior
- Uso: Ordem crítica (ex: transações bancárias)
Parâmetros Detalhados
queueUrl (string, obrigatório)
O que é: URL completa da fila SQS onde a mensagem será enviada.
Formato: https://sqs.{region}.amazonaws.com/{account-id}/{queue-name}
Flow completo para testar:
{
"name": "Teste SQS Send - Queue URL",
"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 Dados",
"parameters": {
"variable": "pedido",
"value": {
"id": "PED-001",
"cliente": "José Roberto",
"total": 250.00
}
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar para Fila",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/pedidos-queue",
"messageBody": "{{pedido}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Pedido enviado para processamento!\nID Mensagem: {{messageId}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Substitua credenciais e URL reais. Sistema retorna messageId único.
messageBody (object/string, obrigatório)
O que é: Conteúdo da mensagem que será enviado para a fila. Pode ser objeto JSON ou string.
Limite: Até 256 KB por mensagem
Flow completo para testar:
{
"name": "Teste SQS Send - Message Body",
"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": "Email Cliente",
"parameters": {
"message": "Digite o email do cliente:",
"variable": "email"
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Email Job",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "{{sqs_queue_url}}",
"messageBody": {
"type": "welcome_email",
"to": "{{email}}",
"subject": "Bem-vindo!",
"template": "welcome-template",
"data": {
"name": "Cliente",
"date": "2025-01-15"
}
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "📧 Email agendado para envio!\nDestinatário: {{email}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite email. Mensagem é enviada com estrutura JSON completa.
delaySeconds (number, opcional)
O que é: Tempo de atraso (em segundos) antes da mensagem ficar disponível para consumo.
Padrão: 0 (disponível imediatamente)
Limite: 0 a 900 segundos (15 minutos)
Flow completo para testar:
{
"name": "Teste SQS Send - Delay",
"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": "Informar",
"parameters": {
"message": "⏰ Agendando lembrete para daqui 5 minutos..."
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar com Delay",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "{{sqs_queue_url}}",
"messageBody": {
"type": "reminder",
"message": "Lembrete: Revisar documento",
"user": "jose.roberto"
},
"delaySeconds": 300
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Lembrete agendado para 5 minutos!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Teste: Mensagem só fica disponível após 5 minutos (300 segundos).
messageAttributes (object, opcional)
O que é: Metadados estruturados da mensagem (filtros, headers customizados).
Formato: { "NomeAtributo": { DataType: "String", StringValue: "valor" } }
Flow completo para testar:
{
"name": "Teste SQS Send - Attributes",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Enviar com Atributos",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "{{sqs_queue_url}}",
"messageBody": {
"orderId": "ORD-123",
"status": "pending"
},
"messageAttributes": {
"Priority": {
"DataType": "String",
"StringValue": "high"
},
"Source": {
"DataType": "String",
"StringValue": "whatsapp-flow"
},
"Version": {
"DataType": "Number",
"StringValue": "1"
}
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Mensagem enviada com metadados!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Atributos são usados para filtrar/rotear mensagens no consumidor.
accessKeyId (string, obrigatório)
O que é: Chave de acesso da conta AWS (credencial de autenticação).
Formato: Alfanumérico, 20 caracteres
secretAccessKey (string, obrigatório)
O que é: Chave secreta da conta AWS (credencial de autenticação).
Formato: Alfanumérico, 40 caracteres
region (string, obrigatório)
O que é: Região AWS onde a fila está hospedada.
Exemplos: us-east-1, us-west-2, eu-west-1, sa-east-1 (São Paulo)
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "sendMessage" |
| accessKeyId | string | Sim | AWS Access Key ID |
| secretAccessKey | string | Sim | AWS Secret Access Key |
| region | string | Sim | Região AWS (ex: us-east-1) |
| queueUrl | string | Sim | URL completa da fila SQS |
| messageBody | object/string | Sim | Conteúdo da mensagem (JSON) |
| delaySeconds | number | Não | Delay de 0-900s (padrão: 0) |
| messageAttributes | object | Não | Metadados da mensagem |
Exemplo 1: Processar Pedido Assíncrono
Objetivo: Enviar pedido para processamento em background
JSON para Importar
{
"name": "Processar Pedido Assíncrono",
"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": "Boas-vindas",
"parameters": {
"message": "🛒 Confirmação de Pedido"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Criar Pedido",
"parameters": {
"variable": "order",
"value": {
"orderId": "ORD-2025-001",
"customer": {
"name": "José Roberto",
"phone": "+5511999999999"
},
"items": [
{ "sku": "PROD-001", "qty": 2, "price": 50.00 },
{ "sku": "PROD-002", "qty": 1, "price": 150.00 }
],
"total": 250.00,
"timestamp": "2025-01-15T10:30:00Z"
}
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Enviar para Fila",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "sa-east-1",
"queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789012/orders-processing",
"messageBody": "{{order}}",
"messageAttributes": {
"OrderType": {
"DataType": "String",
"StringValue": "standard"
},
"Priority": {
"DataType": "String",
"StringValue": "normal"
}
}
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Pedido ORD-2025-001 recebido!\n\n💰 Total: R$ 250,00\n⏳ Processando em background..."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "variable_1" },
{ "source": "variable_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 🛒 Confirmação de Pedido
Sistema: ✅ Pedido ORD-2025-001 recebido!
💰 Total: R$ 250,00
⏳ Processando em background...
Exemplo 2: Enviar Email Assíncrono
Objetivo: Agendar envio de email sem bloquear o flow
JSON para Importar
{
"name": "Agendar Email Assíncrono",
"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": "Nome",
"parameters": {
"message": "Qual é o seu nome?",
"variable": "nome"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Email",
"parameters": {
"message": "Qual é o seu email?",
"variable": "email"
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Agendar Email",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "{{email_queue_url}}",
"messageBody": {
"type": "welcome_email",
"to": "{{email}}",
"subject": "Bem-vindo, {{nome}}!",
"template": "welcome",
"data": {
"customerName": "{{nome}}",
"signupDate": "2025-01-15"
}
},
"delaySeconds": 60
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Obrigado, {{nome}}!\n\n📧 Você receberá um email de boas-vindas em {{email}} nos próximos minutos."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Qual é o seu nome?
Usuário: José Roberto
Sistema: Qual é o seu email?
Usuário: jose@example.com
Sistema: ✅ Obrigado, José Roberto!
📧 Você receberá um email de boas-vindas em jose@example.com nos próximos minutos.
Exemplo 3: Processamento de Imagem
Objetivo: Enviar imagem para processamento assíncrono (resize, compressão)
JSON para Importar
{
"name": "Processar Imagem Assíncrona",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "media_1",
"type": "media",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Receber Imagem",
"parameters": {
"message": "📸 Envie a foto do produto:",
"variable": "foto_produto",
"mediaType": "image"
}
}
},
{
"id": "sqs_1",
"type": "aws_sqs",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar para Processamento",
"parameters": {
"operation": "sendMessage",
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"queueUrl": "{{image_processing_queue}}",
"messageBody": {
"imageUrl": "{{foto_produto}}",
"operations": [
{ "type": "resize", "width": 800, "height": 600 },
{ "type": "compress", "quality": 85 },
{ "type": "watermark", "text": "Minha Loja" }
],
"outputBucket": "processed-images",
"callbackUrl": "https://api.lumina.app.br/webhooks/image-processed"
},
"messageAttributes": {
"ImageType": {
"DataType": "String",
"StringValue": "product"
}
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Foto recebida!\n\n⚙️ Processando imagem...\n📦 Você será notificado quando estiver pronta."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "media_1" },
{ "source": "media_1", "target": "sqs_1" },
{ "source": "sqs_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: 📸 Envie a foto do produto:
Usuário: [envia imagem]
Sistema: ✅ Foto recebida!
⚙️ Processando imagem...
📦 Você será notificado quando estiver pronta.
Resposta do Node
{
"success": true,
"messageId": "f8a7d2e1-c5b4-4d6a-9e8c-1f2a3b4c5d6e"
}
Dead Letter Queue (DLQ)
O que é: Fila para mensagens que falharam no processamento após X tentativas.
Configuração (no AWS Console):
{
"RedrivePolicy": {
"deadLetterTargetArn": "arn:aws:sqs:us-east-1:123456789012:orders-dlq",
"maxReceiveCount": 3
}
}
Uso: - Mensagem falha 3 vezes → movida para DLQ - Analise erros na DLQ - Reprocesse ou descarte
Boas Práticas
✅ SIM:
- Use DLQ para capturar falhas
- Configure visibility timeout adequado
- Use messageAttributes para filtros
- Implemente idempotência no consumidor
- Monitore tamanho da fila no CloudWatch
- Use FIFO queues quando ordem importa
- Valide messageBody antes de enviar
- Configure retry policy
❌ NÃO:
- Não envie dados sensíveis sem criptografia
- Não exceda 256 KB por mensagem
- Não use para respostas síncronas
- Não ignore erros de envio
- Não esqueça de deletar mensagens processadas
- Não use Standard queue se ordem é crítica
Limites AWS SQS
| Item | Limite |
|---|---|
| Tamanho mensagem | 256 KB |
| Retenção | 1 min - 14 dias (padrão: 4 dias) |
| Throughput Standard | Ilimitado |
| Throughput FIFO | 3000 msgs/seg (com batching) |
| Delay máximo | 15 minutos |
| Visibility timeout | 0s - 12 horas |
| Long polling | 0-20 segundos |
Dicas
💡 Batching: Envie múltiplas mensagens com sendMessageBatch() para melhor performance
💡 Long Polling: Configure WaitTimeSeconds > 0 para reduzir custos
💡 Visibilidade: Ajuste VisibilityTimeout baseado no tempo de processamento
💡 Monitoramento: Use CloudWatch para alertas de fila cheia
💡 Custo: SQS cobra por requisição (1 milhão = ~$0.40)
Próximo Node
→ SQS RECEIVE - Receber mensagens da fila → SQS DELETE - Deletar mensagem processada → SNS PUBLISH - Publicar em tópico SNS (broadcast)