Skip to main content
O Convex (ou o motor de fluxo) decide a resposta; o ZapMeow a executa como uma pessoa: espera, mostra “digitando…” ou “gravando áudio…”, e só então envia. Tudo vem da config do tenant da sessão (humanizer, voice e roles, em /admin/tenants/{id}/config). Quem não quer humanizar continua usando POST /api/sendText e sendVoice, que enviam na hora.

Enfileirar

POST /api/{sessão}/outbox responde 202 com o item. O envio acontece em segundo plano, em ordem por conversa (conversas diferentes andam juntas). Estados: queued → sending → sent | failed; áudio com prévia passa por awaiting_preview → queued (aprovado) ou rejected.

Regras (config humanizer)

  • Pausa e presença. Antes de enviar, espera um tempo e mostra a presença (renovada a cada 8 s). Texto: tamanho ÷ charsPerSecond (com ±10%), ou um valor sorteado entre minDelayMs e maxDelayMs. Áudio: a duração do áudio. Sempre limitado a [minDelayMs, maxDelayMs]; maxDelayMs = 0 desliga a pausa. typingEnabled = false mantém a pausa mas sem mostrar “digitando”.
  • Áudio por TTS. O modelo é sempre eleven_v4_turbo, fixo no código: não há recuo para outro modelo e voice.modelId da config não vale para este TTS. A voz vem de voiceId do pedido > papel (pelo nome ou pela etapa) > voice.voiceId. stability e similarity só vão à ElevenLabs se estiverem na config; sem eles valem os parâmetros salvos da voz no painel da ElevenLabs. A chave da ElevenLabs fica no cofre do tenant com o nome elevenlabs_api_key; só o tenant Glow cai na variável ELEVENLABS_API_KEY da plataforma. A saída é Ogg Opus (ZAPMEOW_TTS_FORMAT, padrão opus_48000_32) e vai como nota de voz; outro formato vai como áudio comum.
  • Tags de voz. O v4 turbo interpreta tags entre colchetes, de entonação e de efeito sonoro ([warmly], [laughs softly], [pausa], [sussurrando], [som de porta]). O TTS comum da ElevenLabs não tem gerador automático de tags (o expressive_mode existe só no ElevenLabs Agents, que a ligação já usa): quem escreve a resposta (Convex ou motor de fluxo) deve incluir as tags no text. O ZapMeow entrega o texto com as tags ao TTS e nunca as manda ao lead: no envio como texto e no fallbackText elas são removidas (só as reconhecidas; [Glow] ou [1] ficam). Texto só com tags falha em vez de sair vazio.
  • Prévia. Com audioPreview = true (padrão) o áudio gerado não sai: o item fica em awaiting_preview, sem presença nem mensagem para o lead. Toque com GET …/outbox/{id}/audio; envie com POST …/approve ou descarte com POST …/reject ({"asText": true} manda a mesma resposta como texto).
  • Envio direto por etapa. Etapas em audioDirectStages (sem diferenciar maiúsculas) pulam a prévia. Com audioPreview = false nenhum áudio passa por prévia.
  • Áudio responde áudio. Com audioReplyToAudio = true e as = auto, a resposta sai em áudio quando a última mensagem do lead foi áudio.
  • Aviso de assistente virtual. Com virtualAssistantNotice = true, a primeira mensagem de cada conversa é precedida do aviso (virtualAssistantText ou um texto padrão), uma vez só. No áudio com prévia, o aviso sai junto com o áudio aprovado.

Prévia e acompanhamento

Eventos no webhook e no stream: outbox.preview (há áudio esperando OK), outbox.sent e outbox.failed, com o item no payload.

Detalhes

  • O áudio é apagado depois de enviado ou recusado. Itens sent, failed e rejected somem após 14 dias.
  • Reinício: o que estava sending vira failed (pode ter saído; não repete); o que estava queued segue depois de 20 s.
  • Um áudio que espera prévia não trava as mensagens seguintes da mesma conversa. Quem decide a resposta controla a ordem.
  • Erros: 400 corpo inválido, 404 item de outra sessão ou inexistente, 409 estado errado.