feat(ivr): upload de áudio pro prompt do IVR
Pedido do usuário: "adiciona upload de áudio pro prompt do IVR" — até aqui o prompt era só texto livre (na prática, sempre um tom padrão, nunca voz de verdade). `POST /ivr-menus/:id/prompt` (multipart via @fastify/multipart — primeiro upload de arquivo binário desta API) só aceita WAV (cabeçalho RIFF/WAVE validado antes de gravar; esta implantação do FreeSWITCH não tem mod_shout, então MP3 nunca funcionaria de qualquer forma). Gravado num bind mount NOVO (./data/ivr-prompts no host ↔ /ivr-prompts no container freeswitch) — mesma convenção já usada 3x neste projeto pra arquivo que o FreeSWITCH precisa enxergar de verdade (gateways externos, filas do callcenter, spool de gravação), mas na direção contrária: apps/api (host) escreve o que o usuário sobe, o FreeSWITCH lê ao vivo durante play_and_get_digits. Um fetch em rede (S3/HTTP) durante uma chamada ativa foi descartado de propósito — latência/confiabilidade desnecessárias pra um prompt de poucos segundos. GET /ivr-menus/:id/prompt (autenticado) serve o preview — mesmo princípio do player de gravações, nunca uma URL direta pro storage. Achado real corrigido antes de commitar: minha primeira versão do delete de menu deixava o .wav órfão no disco — agora deletar o menu ou trocar/remover o prompt sempre limpa o arquivo, confirmado com um teste real de upload+delete. Tela "Telefonia > IVR" ganhou upload/troca/remoção de áudio por menu + player de preview. Testado ponta a ponta com um WAV real de 44.1kHz/mono (não o formato "nativo" de telefonia, de propósito, pra confirmar que funciona com o que uma pessoa qualquer gravaria): softphone externo discou o DID, play_and_get_digits abriu e tocou o arquivo até o fim duas vezes (mod_sndfile resample automático, sem erro no log), colheu o dígito real e bridged corretamente com o ramal de destino. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
@@ -91,6 +91,14 @@ services:
|
||||
# host e precisa enxergar os mesmos arquivos que o FreeSWITCH grava
|
||||
# (agente.md secao 90-91) — ver docs/RECORDING.md.
|
||||
- ./data/recordings-spool:/recordings
|
||||
# Prompts de áudio do IVR (PHASE 59) — mesmo raciocínio do bind
|
||||
# mount acima, mas na direção contrária: apps/api (host) ESCREVE o
|
||||
# arquivo que o usuário sobe, e o FreeSWITCH precisa LER esse mesmo
|
||||
# arquivo ao vivo durante `play_and_get_digits`. Só funciona como
|
||||
# bind mount de disco local — um fetch em rede (S3/HTTP) durante
|
||||
# uma chamada ativa seria latência/confiabilidade desnecessárias
|
||||
# pra um prompt de poucos segundos.
|
||||
- ./data/ivr-prompts:/ivr-prompts
|
||||
# Event Socket (8021) NUNCA publicado — só alcançável por outros
|
||||
# containers na rede interna do compose (agente.md secao 22).
|
||||
# SIP (5060) e RTP (16384-16584, range fixo no Dockerfile) publicados
|
||||
|
||||
Reference in New Issue
Block a user