Configure notificações automáticas em tempo real sobre suas transcrições. Aprenda como configurar webhooks, implementar segurança e integrar com seus sistemas.
Receba atualizações instantâneas sobre o status das transcrições
Automatize fluxos de trabalho baseados em eventos
Monitore e registre eventos para análise
Processe múltiplas transcrições simultaneamente
transcription.started
Transcrição iniciada com sucesso
{
"event": "transcription.started",
"data": {
"id": "txn_abc123",
"status": "started",
"file_name": "reuniao_cliente.mp3",
"estimated_duration": 300,
"created_at": "2024-01-15T10:30:00Z"
}
}
Configure monitoramento para acompanhar progresso
transcription.progress
Progresso da transcrição atualizado
{
"event": "transcription.progress",
"data": {
"id": "txn_abc123",
"status": "processing",
"progress": 45,
"estimated_completion": "2024-01-15T10:35:00Z",
"current_stage": "audio_analysis"
}
}
Atualize interface do usuário com progresso
transcription.completed
Transcrição concluída com sucesso
{
"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"
}
}
Processe resultado e notifique usuários
transcription.failed
Transcrição falhou por algum motivo
{
"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"
}
}
Notifique usuário sobre erro e possíveis correções
credits.low
Créditos estão ficando baixos
{
"event": "credits.low",
"data": {
"current_balance": 25,
"threshold": 50,
"user_id": "user_xyz789",
"recommended_action": "purchase_credits"
}
}
Notifique usuário para comprar mais créditos
credits.depleted
Créditos esgotados
{
"event": "credits.depleted",
"data": {
"current_balance": 0,
"user_id": "user_xyz789",
"last_purchase": "2024-01-10T14:20:00Z",
"pending_transcriptions": 3
}
}
Bloquear novas transcrições até recarga
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);
});
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"
}'
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')
);
}
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
}
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
// 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);
}
?>
Sempre valide a assinatura HMAC dos webhooks
Proteja seu endpoint contra abuso
Use sempre conexões seguras
Configure timeouts apropriados
O VozParaTexto implementa retry automático com backoff exponencial para garantir que você receba os webhooks mesmo em caso de indisponibilidade temporária.
Tentativa | Timing | Timeout | Ação |
---|---|---|---|
1ª tentativa | Imediato | 5 segundos | Envio inicial do webhook |
2ª tentativa | 1 minuto depois | 10 segundos | Retry automático se status != 200 |
3ª tentativa | 5 minutos depois | 15 segundos | Segundo retry com timeout maior |
4ª tentativa | 15 minutos depois | 20 segundos | Terceiro retry com timeout maior |
5ª tentativa | 1 hora depois | 30 segundos | Último retry antes de desabilitar |
Desabilitação | Após 5 falhas | N/A | Webhook marcado como inativo |
// Teste manual do endpoint
curl -X POST "https://seu-site.com/webhook" \
-H "Content-Type: application/json" \
-d '{"test": true}'
// Debug payload
app.use('/webhook', (req, res, next) => {
console.log('Raw body:', req.body);
console.log('Headers:', req.headers);
next();
});
// Debug assinatura
console.log('Expected:', expectedSignature);
console.log('Received:', receivedSignature);
console.log('Payload length:', payload.length);