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:
@@ -150,10 +150,38 @@ recém-criado atendeu, tocou o prompt, colheu o dígito com DTMF real
|
||||
compilador produz XML funcionalmente idêntico ao testado manualmente na
|
||||
PHASE 56.
|
||||
|
||||
## Upload de áudio pro prompt (PHASE 59)
|
||||
|
||||
`POST /ivr-menus/:id/prompt` (multipart, campo `file`) — só aceita WAV
|
||||
(cabeçalho RIFF/WAVE validado antes de gravar; sem `mod_shout` nesta
|
||||
implantação, MP3 nunca funcionaria mesmo). Gravado num bind mount NOVO
|
||||
compartilhado com o container do FreeSWITCH (`./data/ivr-prompts` no
|
||||
host ↔ `/ivr-prompts` no container) — mesmo raciocínio já usado pras
|
||||
gravações de chamada (`./data/recordings-spool`), mas na direção
|
||||
contrária: aqui é `apps/api` (host) que ESCREVE e o FreeSWITCH que LÊ.
|
||||
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, e esta é a MESMA convenção já usada 3x neste projeto
|
||||
pra arquivos que o FreeSWITCH precisa enxergar (gateways externos, filas
|
||||
do callcenter, spool de gravação).
|
||||
|
||||
`greeting` passa a guardar o path como o FreeSWITCH enxerga
|
||||
(`/ivr-prompts/<tenantId>/<menuId>.wav`), nunca o path do host.
|
||||
`GET /ivr-menus/:id/prompt` (autenticado, `ivr.view`) serve o preview —
|
||||
mesmo princípio do player de gravações, nunca uma URL direta pro
|
||||
storage/disco. Deletar o menu ou trocar/remover o prompt sempre limpa o
|
||||
arquivo do disco (nunca deixa órfão).
|
||||
|
||||
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/exportaria): 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.
|
||||
|
||||
## O que falta
|
||||
|
||||
- Sem pipeline de upload/TTS de prompt de áudio — hoje é texto livre
|
||||
(tom padrão ou um caminho/URL que o FreeSWITCH já sabe tocar).
|
||||
- Sem TTS (texto→voz) — só upload de arquivo WAV já gravado.
|
||||
- Menu de IVR não suporta sub-menus (uma opção levando a OUTRO IVR) nem
|
||||
destino "fila" — só ramal, dentro do contexto `default`.
|
||||
- Tela de frontend "Rotas de Entrada" cobre só CRUD simples (DID →
|
||||
|
||||
Reference in New Issue
Block a user