Skip to content

WhatsApp Audio — Pipeline de Transcrição (STT)

Visão Geral

O MediaFetcherService baixa áudios enviados por WhatsApp (voz/PTT) e os encaminha para transcrição via AssistantService.transcribeAudio(). O texto transcrito é então tratado como mensagem de texto pelo fluxo de IA (pedido do cliente ou assistente admin).


Arquivos

ArquivoPapel
backend/src/whatsapp-ordering/media-fetcher.service.tsFetch de bytes de áudio (Meta + Evolution)
backend/src/whatsapp-ordering/whatsapp-ordering.controller.tsEntry point webhook — detecta message.type === 'audio'
backend/src/whatsapp-ordering/conversation.schema.tsSchema de conversa com AudioTranscriptEntry[]
backend/src/assistant/assistant.service.tstranscribeAudio(bytes, mimeType, filename)

Fluxo Completo

WhatsApp (Meta/Evolution)


POST /webhooks/whatsapp/:tenantId   (WhatsAppOrderingController)

  ├── message.type === 'text' → passa direto para AI

  └── message.type === 'audio'

        ├── Verifica duração ≤ 60s (cap de tamanho)
        │     Se > 60s → responde "Áudio muito longo" e retorna

        ├── MediaFetcherService.fetchMeta(mediaId, tenantId)
        │     ou MediaFetcherService.fetchEvolution(messageId, baseUrl, apiKey)

        ├── AssistantService.transcribeAudio(bytes, 'audio/ogg', 'audio.ogg')

        ├── persistTranscript(tenantId, phone, { source, mediaId, durationSec, transcript })

        └── text = transcript → fluxo AI normal (admin ou customer)

MediaFetcherService

fetchMeta(mediaId, tenantId)

  • Usa tenant.whatsappConfig.metaAccessToken (por tenant).
  • Passo 1: GET https://graph.facebook.com/v18.0/{mediaId} → resolve URL presigned.
  • Passo 2: Download dos bytes brutos com o mesmo token.
  • Retorna Buffer.

fetchEvolution(messageId, instanceBaseUrl, apiKey)

  • Chama GET {instanceBaseUrl}/message/getBase64FromMediaMessage/{messageId} com header apikey.
  • Decodifica data.base64Buffer.

Auditoria de Transcrições

Cada áudio processado gera uma entrada no campo WhatsAppConversation.transcripts[]:

CampoTipoDescrição
source'meta' | 'evolution'Provedor do áudio
mediaIdstringID do media no provedor
durationSecnumberDuração declarada pelo provedor
transcriptstringTexto transcrito
receivedAtDateTimestamp

A persistência é feita via upsert em WhatsAppConversation (keyed por phone + tenant).


Limites e Restrições

ParâmetroValor
Duração máxima de áudio60 segundos
Formato aceitoaudio/ogg (WhatsApp PTT/voice)
Rate limit webhookSem throttle próprio (depende do provider)
Tenant sem metaAccessTokenBadRequestException ("no Meta access token configured")

Configuração

Para habilitar áudio via Meta Cloud API:

  1. Configure WHATSAPP_VERIFY_TOKEN nas variáveis de ambiente.
  2. No documento Tenant, salve whatsappConfig.metaAccessToken com o token permanente da Meta.
  3. No painel Meta for Developers, aponte o webhook para POST /webhooks/whatsapp/:tenantId.

Para Evolution API:

  1. Configure evolutionInstance no documento Branch (cada branch pode ter instância própria).
  2. A chave de API é resolvida via WhatsAppService.resolveInstance(tenantId).

Relacionados

Lançado sob a licença MIT.