Voltar
8 min de leitura
Recursos Avançados

Webhooks e Notificações

Configure notificações automáticas em tempo real sobre suas transcrições. Aprenda como configurar webhooks, implementar segurança e integrar com seus sistemas.

Por Que Usar Webhooks?

Notificações em Tempo Real

Receba atualizações instantâneas sobre o status das transcrições

  • Elimina necessidade de polling
  • Reduz latência de resposta
  • Melhora experiência do usuário
  • Economiza recursos de servidor

Integração Automatizada

Automatize fluxos de trabalho baseados em eventos

  • Processamento automático de resultados
  • Triggers para próximas etapas
  • Integração com sistemas existentes
  • Redução de intervenção manual

Monitoramento Avançado

Monitore e registre eventos para análise

  • Logs detalhados de eventos
  • Métricas de performance
  • Alertas de falhas
  • Rastreamento de SLA

Escalabilidade

Processe múltiplas transcrições simultaneamente

  • Paralelização de processamento
  • Distribuição de carga
  • Handling de alto volume
  • Arquitetura orientada a eventos

Eventos Disponíveis

transcription.started

Uma vez por transcrição

Transcrição iniciada com sucesso

Exemplo de payload:

{
  "event": "transcription.started",
  "data": {
    "id": "txn_abc123",
    "status": "started",
    "file_name": "reuniao_cliente.mp3",
    "estimated_duration": 300,
    "created_at": "2024-01-15T10:30:00Z"
  }
}

Próximos passos sugeridos:

Configure monitoramento para acompanhar progresso

transcription.progress

A cada 10-20% de progresso

Progresso da transcrição atualizado

Exemplo de payload:

{
  "event": "transcription.progress",
  "data": {
    "id": "txn_abc123",
    "status": "processing",
    "progress": 45,
    "estimated_completion": "2024-01-15T10:35:00Z",
    "current_stage": "audio_analysis"
  }
}

Próximos passos sugeridos:

Atualize interface do usuário com progresso

transcription.completed

Uma vez por transcrição

Transcrição concluída com sucesso

Exemplo de payload:

{
  "event": "transcription.completed",
  "data": {
    "id": "txn_abc123",
    "status": "completed",
    "result": {
      "text": "Texto da transcrição...",
      "confidence": 0.95,
      "duration": 287,
      "word_count": 423
    },
    "completed_at": "2024-01-15T10:34:30Z"
  }
}

Próximos passos sugeridos:

Processe resultado e notifique usuários

transcription.failed

Quando ocorre erro

Transcrição falhou por algum motivo

Exemplo de payload:

{
  "event": "transcription.failed",
  "data": {
    "id": "txn_abc123",
    "status": "failed",
    "error": {
      "code": "invalid_audio_format",
      "message": "Formato de áudio não suportado",
      "details": "Expected MP3, WAV, or M4A"
    },
    "failed_at": "2024-01-15T10:32:15Z"
  }
}

Próximos passos sugeridos:

Notifique usuário sobre erro e possíveis correções

credits.low

Quando saldo < limite configurado

Créditos estão ficando baixos

Exemplo de payload:

{
  "event": "credits.low",
  "data": {
    "current_balance": 25,
    "threshold": 50,
    "user_id": "user_xyz789",
    "recommended_action": "purchase_credits"
  }
}

Próximos passos sugeridos:

Notifique usuário para comprar mais créditos

credits.depleted

Quando saldo = 0

Créditos esgotados

Exemplo de payload:

{
  "event": "credits.depleted",
  "data": {
    "current_balance": 0,
    "user_id": "user_xyz789",
    "last_purchase": "2024-01-10T14:20:00Z",
    "pending_transcriptions": 3
  }
}

Próximos passos sugeridos:

Bloquear novas transcrições até recarga

Configuração Passo a Passo

1

1. Configure o Endpoint

10-15 minutos

Configure URL do seu servidor para receber webhooks

// Exemplo de endpoint Node.js/Express
const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

app.post('/webhooks/vozparatexto', (req, res) => {
  // Verificar assinatura (recomendado)
  const signature = req.headers['x-vozparatexto-signature'];
  const payload = JSON.stringify(req.body);
  
  // Validar webhook (exemplo abaixo)
  if (!verifySignature(payload, signature)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Processar evento
  const { event, data } = req.body;
  console.log('Evento recebido:', event);
  
  // Responder rapidamente
  res.status(200).send('OK');
  
  // Processar assincronamente
  processWebhookEvent(event, data);
});
2

2. Registre o Webhook

5-10 minutos

Configure webhook no dashboard ou via API

// Via Dashboard
1. Acesse Dashboard → Configurações → Webhooks
2. Clique em "Novo Webhook"
3. Insira URL do seu endpoint
4. Selecione eventos desejados
5. Configure secret key (opcional)
6. Teste e salve

// Via API
curl -X POST "https://api.vozparatexto.com.br/v1/webhooks" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-site.com/webhooks/vozparatexto",
    "events": ["transcription.*", "credits.low"],
    "secret": "sua_chave_secreta_aqui"
  }'
3

3. Implemente Validação

5-10 minutos

Valide assinatura para garantir segurança

function verifySignature(payload, signature) {
  const secret = process.env.WEBHOOK_SECRET;
  if (!secret || !signature) return false;
  
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
    
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}
4

4. Teste e Monitore

15-30 minutos

Teste funcionamento e configure monitoramento

// Teste com transcrição real
function testWebhook() {
  // Faça upload de arquivo pequeno
  // Monitore logs do seu servidor
  // Verifique se eventos são recebidos
  // Valide estrutura do payload
}

// Monitoramento básico
function monitorWebhooks() {
  // Log todos os eventos recebidos
  // Monitore falhas de validação
  // Alerte sobre webhooks perdidos
  // Meça latência de processamento
}

Exemplos de Implementação

Node.js + Express

const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json({ limit: '10mb' }));

// Middleware para capturar raw body
app.use('/webhooks', (req, res, next) => {
  req.rawBody = JSON.stringify(req.body);
  next();
});

app.post('/webhooks/vozparatexto', async (req, res) => {
  try {
    // Verificar assinatura
    const signature = req.headers['x-vozparatexto-signature'];
    if (!verifySignature(req.rawBody, signature)) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    const { event, data } = req.body;

    // Responder rapidamente
    res.status(200).json({ received: true });

    // Processar evento assincronamente
    await processEvent(event, data);
    
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

async function processEvent(event, data) {
  switch (event) {
    case 'transcription.completed':
      await handleTranscriptionCompleted(data);
      break;
    case 'transcription.failed':
      await handleTranscriptionFailed(data);
      break;
    case 'credits.low':
      await handleCreditsLow(data);
      break;
    default:
      console.log('Unknown event:', event);
  }
}

function verifySignature(payload, signature) {
  const secret = process.env.WEBHOOK_SECRET;
  if (!secret || !signature) return false;
  
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
    
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

PHP

<?php

// webhook-handler.php
$secret = getenv('WEBHOOK_SECRET');
$signature = $_SERVER['HTTP_X_VOZPARATEXTO_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');

// Verificar assinatura
if (!verifySignature($payload, $signature, $secret)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Decodificar payload
$data = json_decode($payload, true);
if (!$data) {
    http_response_code(400);
    exit('Invalid JSON');
}

// Responder rapidamente
http_response_code(200);
echo json_encode(['received' => true]);

// Processar evento
processEvent($data['event'], $data['data']);

function verifySignature($payload, $signature, $secret) {
    if (empty($secret) || empty($signature)) {
        return false;
    }
    
    $expectedSignature = hash_hmac('sha256', $payload, $secret);
    $receivedSignature = str_replace('sha256=', '', $signature);
    
    return hash_equals($expectedSignature, $receivedSignature);
}

function processEvent($event, $data) {
    switch ($event) {
        case 'transcription.completed':
            handleTranscriptionCompleted($data);
            break;
        case 'transcription.failed':
            handleTranscriptionFailed($data);
            break;
        case 'credits.low':
            handleCreditsLow($data);
            break;
        default:
            error_log("Unknown webhook event: $event");
    }
}

function handleTranscriptionCompleted($data) {
    // Implementar lógica de processamento
    $transcriptionId = $data['id'];
    $result = $data['result'];
    
    // Exemplo: salvar no banco de dados
    // updateTranscriptionStatus($transcriptionId, 'completed', $result);
    
    // Exemplo: enviar email para usuário
    // sendCompletionEmail($transcriptionId);
}

?>

Segurança e Melhores Práticas

Validação de Assinatura

Crítico

Sempre valide a assinatura HMAC dos webhooks

  • Configure secret key única
  • Implemente verificação HMAC SHA-256
  • Use comparação timing-safe
  • Rejeite requests sem assinatura válida

Rate Limiting

Alto

Proteja seu endpoint contra abuso

  • Limite requests por IP
  • Implemente backoff exponencial
  • Configure alertas para tráfego anômalo
  • Use CDN ou proxy reverso

HTTPS Obrigatório

Crítico

Use sempre conexões seguras

  • Configure certificado SSL válido
  • Redirecione HTTP para HTTPS
  • Use TLS 1.2 ou superior
  • Valide certificados

Timeout Adequado

Médio

Configure timeouts apropriados

  • Responda em até 5 segundos
  • Processe eventos assincronamente
  • Configure timeout no servidor
  • Implemente fila para processamento lento

Mecanismo de Retry

O VozParaTexto implementa retry automático com backoff exponencial para garantir que você receba os webhooks mesmo em caso de indisponibilidade temporária.

TentativaTimingTimeoutAção
1ª tentativaImediato5 segundosEnvio inicial do webhook
2ª tentativa1 minuto depois10 segundosRetry automático se status != 200
3ª tentativa5 minutos depois15 segundosSegundo retry com timeout maior
4ª tentativa15 minutos depois20 segundosTerceiro retry com timeout maior
5ª tentativa1 hora depois30 segundosÚltimo retry antes de desabilitar
DesabilitaçãoApós 5 falhasN/AWebhook marcado como inativo

Solução de Problemas

Webhooks não estão sendo recebidos

Possíveis causas:

  • URL do webhook incorreta ou inacessível
  • Firewall bloqueando requests
  • Servidor webhook inativo
  • Configuração SSL inválida

Soluções:

  • Verifique URL e conectividade
  • Configure firewall para permitir IPs do VozParaTexto
  • Monitore logs do servidor
  • Teste endpoint manualmente
  • Valide certificado SSL

Debug:

// Teste manual do endpoint
curl -X POST "https://seu-site.com/webhook" \
  -H "Content-Type: application/json" \
  -d '{"test": true}'

Webhooks recebidos mas payload vazio

Possíveis causas:

  • Problemas de parsing JSON
  • Middleware interferindo
  • Tamanho do payload muito grande
  • Encoding incorreto

Soluções:

  • Verifique parsing de JSON no servidor
  • Desabilite middlewares desnecessários
  • Aumente limite de payload
  • Configure UTF-8 encoding
  • Log payload raw antes do parsing

Debug:

// Debug payload
app.use('/webhook', (req, res, next) => {
  console.log('Raw body:', req.body);
  console.log('Headers:', req.headers);
  next();
});

Validação de assinatura falhando

Possíveis causas:

  • Secret key incorreto
  • Formato de assinatura errado
  • Encoding do payload diferente
  • Timing attack na comparação

Soluções:

  • Verifique secret key configurado
  • Use formato correto de assinatura
  • Mantenha encoding consistente
  • Use crypto.timingSafeEqual
  • Log assinaturas para debug

Debug:

// Debug assinatura
console.log('Expected:', expectedSignature);
console.log('Received:', receivedSignature);
console.log('Payload length:', payload.length);

Pronto para configurar webhooks?

Configure notificações automáticas e automatize seus fluxos de trabalho. Integre o VozParaTexto perfeitamente com seus sistemas existentes.

Continue aprendendo