Pular para conteúdo

MEDIA - Capturar Mídia

O que é este Node?

O MEDIA é o node responsável por capturar arquivos de mídia (imagem, vídeo, áudio, documentos) enviados pelo usuário através do WhatsApp/Telegram.

Por que este Node existe?

Capturar arquivos permite interações ricas e casos de uso avançados. O MEDIA existe para:

  1. Receber arquivos: Captura imagens, vídeos, áudios, PDFs enviados pelo usuário
  2. Validação de tipo: Aceita apenas tipos específicos (ex: apenas imagens)
  3. OCR/Análise: Permite processar documentos, ler textos em fotos, etc.
  4. Suporte visual: Usuário envia foto do problema ao invés de descrever
  5. Comprovantes: Captura recibos, documentos, fotos de produtos

Como funciona internamente?

Quando o MEDIA é executado, o sistema:

  1. Pausa o flow e exibe a mensagem
  2. Aguarda envio de arquivo pelo usuário
  3. Valida tipo: Verifica se é imagem, vídeo, áudio, etc.
  4. Valida mediaTypes: Se definido, aceita apenas tipos permitidos
  5. Faz upload: Salva o arquivo no servidor
  6. Retorna URL: Salva URL do arquivo na variável
  7. Continua o flow

Código interno (basic-flow-executor.service.ts:283-301):

private async executeMedia(parameters: any, context: any): Promise<any> {
  const { message, variable, mediaTypes } = parameters;

  return {
    success: true,
    action: 'media_requested',
    inputType: 'media',
    message: message || 'Please send an image, video, or audio file:',
    variable: variable || 'user_media',
    mediaTypes: mediaTypes || ['image', 'video', 'audio'],
    validation: {
      required: true,
      type: 'media'
    },
    awaitingUserInput: true
  };
}

Quando você DEVE usar este Node?

Use MEDIA sempre que precisar receber arquivos do usuário:

Casos de uso:

  1. Suporte técnico: "Envie uma foto do problema"
  2. Documentos: "Envie foto do RG/CNH"
  3. Comprovantes: "Envie o comprovante de pagamento"
  4. Produtos: "Envie foto do produto com defeito"
  5. OCR: "Envie foto da conta de luz para ler dados"
  6. Áudio: "Grave um áudio com sua dúvida"
  7. Vídeo: "Grave um vídeo mostrando o erro"

Quando NÃO usar MEDIA:

  • Texto: Se precisa apenas texto, use INPUT
  • Selfie com validação facial: Requer integração específica de reconhecimento facial

Parâmetros Detalhados

message (string, obrigatório)

O que é: A mensagem solicitando que o usuário envie o arquivo.

Flow completo para testar:

{
  "name": "Teste MEDIA - Message",
  "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": "Pedir Arquivo",
        "parameters": {
          "message": "Por favor, envie uma imagem, vídeo ou áudio"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Arquivo recebido! URL: {{user_media}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "media_1" },
    { "source": "media_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

variable (string, opcional)

O que é: Nome da variável onde a URL do arquivo será salva.

Padrão: "user_media"

Flow completo para testar:

{
  "name": "Teste MEDIA - Variable",
  "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": "Suporte",
        "parameters": {
          "message": "Vamos analisar o problema 🔧"
        }
      }
    },
    {
      "id": "media_1",
      "type": "media",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Foto Problema",
        "parameters": {
          "message": "Envie foto do problema:",
          "variable": "foto_problema"
        }
      }
    },
    {
      "id": "media_2",
      "type": "media",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Foto Nota Fiscal",
        "parameters": {
          "message": "Agora envie foto da nota fiscal:",
          "variable": "foto_nota"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "📸 Fotos recebidas!\n\nProblema: {{foto_problema}}\nNota: {{foto_nota}}\n\nAnalisando..."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "media_1" },
    { "source": "media_1", "target": "media_2" },
    { "source": "media_2", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

mediaTypes (array, opcional)

O que é: Define quais tipos de mídia são aceitos.

Padrão: ["image", "video", "audio"] (aceita todos)

Valores: image, video, audio, document

Flow completo para testar mediaTypes=["image"]:

{
  "name": "Teste MEDIA - Apenas Imagens",
  "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": "Apenas Imagens",
        "parameters": {
          "message": "Envie uma foto (somente imagens aceitas):",
          "variable": "foto",
          "mediaTypes": ["image"]
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "📷 Foto recebida: {{foto}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "media_1" },
    { "source": "media_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Envie imagem - aceita! Envie vídeo - rejeita!

Parâmetros

Campo Tipo Obrigatório Descrição
message string Sim Mensagem solicitando arquivo
variable string Não Nome da variável (padrão: "user_media")
mediaTypes array Não Tipos aceitos (padrão: ["image","video","audio"])

Exemplo 1: Suporte com Foto

Objetivo: Capturar foto do problema do cliente

JSON para Importar

{
  "name": "Suporte - Foto do Problema",
  "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": "🛠️ Suporte Técnico - Vamos resolver!"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Descrever Problema",
        "parameters": {
          "message": "Descreva o problema em poucas palavras:",
          "variable": "descricao"
        }
      }
    },
    {
      "id": "media_1",
      "type": "media",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Enviar Foto",
        "parameters": {
          "message": "📸 Envie uma foto mostrando o problema:",
          "variable": "foto_problema",
          "mediaTypes": ["image"]
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Protocolo",
        "parameters": {
          "message": "✅ Chamado aberto!\n\n🎫 Protocolo: #12345\n📝 Problema: {{descricao}}\n📷 Foto: Recebida\n\n⏱️ Retorno em até 2 horas"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "media_1" },
    { "source": "media_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Exemplo 2: Envio de Documentos

Objetivo: Capturar documentos (RG, CNH, etc.)

JSON para Importar

{
  "name": "Cadastro - Envio de Documentos",
  "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": "Intro",
        "parameters": {
          "message": "📋 Vamos finalizar seu cadastro com envio dos documentos"
        }
      }
    },
    {
      "id": "media_1",
      "type": "media",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "RG Frente",
        "parameters": {
          "message": "Envie foto do RG (frente):",
          "variable": "rg_frente",
          "mediaTypes": ["image"]
        }
      }
    },
    {
      "id": "media_2",
      "type": "media",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "RG Verso",
        "parameters": {
          "message": "Agora envie o verso do RG:",
          "variable": "rg_verso",
          "mediaTypes": ["image"]
        }
      }
    },
    {
      "id": "media_3",
      "type": "media",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Comprovante",
        "parameters": {
          "message": "Por fim, envie comprovante de residência:",
          "variable": "comprovante",
          "mediaTypes": ["image", "document"]
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Finalizar",
        "parameters": {
          "message": "✅ DOCUMENTOS RECEBIDOS!\n\n📄 RG Frente: ✓\n📄 RG Verso: ✓\n📄 Comprovante: ✓\n\n⏱️ Análise em até 24h"
        }
      }
    },
    {
      "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": "media_2" },
    { "source": "media_2", "target": "media_3" },
    { "source": "media_3", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Exemplo 3: Áudio para Transcrição

Objetivo: Capturar áudio do usuário

JSON para Importar

{
  "name": "Captura de Áudio",
  "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",
        "parameters": {
          "message": "🎤 Grave um áudio com sua dúvida ou reclamação"
        }
      }
    },
    {
      "id": "media_1",
      "type": "media",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Capturar Áudio",
        "parameters": {
          "message": "Pressione e segure para gravar:",
          "variable": "audio_usuario",
          "mediaTypes": ["audio"]
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Áudio recebido!\n\n🎧 Processando transcrição...\n\n⏱️ Aguarde alguns segundos"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "media_1" },
    { "source": "media_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Resposta do Node

{
  "success": true,
  "action": "media_requested",
  "inputType": "media",
  "message": "Envie uma foto do problema:",
  "variable": "foto_problema",
  "mediaTypes": ["image", "video", "audio"],
  "validation": {
    "required": true,
    "type": "media"
  },
  "awaitingUserInput": true
}

Formato do Arquivo Capturado

Quando o usuário envia o arquivo, a variável contém a URL:

https://storage.exemplo.com/uploads/abc123.jpg

Ou objeto detalhado:

{
  "url": "https://storage.exemplo.com/uploads/abc123.jpg",
  "type": "image",
  "size": 245678,
  "filename": "foto.jpg"
}

Tipos de Mídia

Tipo Descrição Extensões
image Imagens jpg, jpeg, png, gif, webp
video Vídeos mp4, avi, mov, webm
audio Áudios mp3, ogg, wav, m4a
document Documentos pdf, doc, docx, txt

Validação Automática

O node MEDIA valida automaticamente:

Tipo de arquivo: Verifica se está em mediaTypes permitidos ✅ Formato: Valida extensão do arquivo ✅ Required: Arquivo obrigatório por padrão ✅ Upload: Faz upload seguro para storage

Se usuário enviar tipo inválido, sistema pede novamente.

Casos de Uso Comuns

Caso mediaTypes Descrição
Foto de produto ["image"] Apenas imagens
Suporte técnico ["image", "video"] Foto ou vídeo
Comprovantes ["image", "document"] Foto ou PDF
Mensagem de voz ["audio"] Apenas áudio
Qualquer arquivo ["image", "video", "audio", "document"] Todos

Dicas

💡 Especifique o tipo: "Envie uma FOTO" ao invés de "Envie arquivo" 💡 Use mediaTypes: Restrinja a tipos necessários 💡 Exemplo visual: Mostre exemplo do que você quer 💡 Tamanho: Considere limites de tamanho no WhatsApp (16MB) 💡 Processamento: Use API de OCR/análise para extrair dados

Boas Práticas

SIM: - Defina mediaTypes específico quando possível - Indique claramente qual arquivo enviar - Confirme recebimento com mensagem

NÃO: - Não aceite todos os tipos se não precisa - Não deixe o usuário sem feedback após envio

Próximos Passos

LOCATION - Capturar localização GPS → INPUT - Capturar texto livre