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:
- Receber arquivos: Captura imagens, vídeos, áudios, PDFs enviados pelo usuário
- Validação de tipo: Aceita apenas tipos específicos (ex: apenas imagens)
- OCR/Análise: Permite processar documentos, ler textos em fotos, etc.
- Suporte visual: Usuário envia foto do problema ao invés de descrever
- Comprovantes: Captura recibos, documentos, fotos de produtos
Como funciona internamente?
Quando o MEDIA é executado, o sistema:
- Pausa o flow e exibe a mensagem
- Aguarda envio de arquivo pelo usuário
- Valida tipo: Verifica se é imagem, vídeo, áudio, etc.
- Valida mediaTypes: Se definido, aceita apenas tipos permitidos
- Faz upload: Salva o arquivo no servidor
- Retorna URL: Salva URL do arquivo na variável
- 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:
- Suporte técnico: "Envie uma foto do problema"
- Documentos: "Envie foto do RG/CNH"
- Comprovantes: "Envie o comprovante de pagamento"
- Produtos: "Envie foto do produto com defeito"
- OCR: "Envie foto da conta de luz para ler dados"
- Áudio: "Grave um áudio com sua dúvida"
- 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