Eu já conversava por voz com a Edwiges dentro do meu WSL, o ambiente Linux que uso no Windows. O Whisper escuta, a Edwiges responde e o Kokoro fala. Funcionava bem. Só que eu precisava estar no meu computador, olhando para o terminal.

Eu queria que, quando acontecesse alguma coisa, o aviso chegasse até onde eu estivesse. E o único canal que sempre está comigo é o telefone.

Eu queria ser acordado se o ambiente com Kubernetes que eu gerencio ficasse fora do ar. Já havia monitoramento. Faltava fazer o alerta sair da tela e chegar até mim. Então construí um comando para a Edwiges gerar o recado com a ElevenLabs e pedir a ligação à Twilio.

Esta é a primeira de três partes. Aqui conto como fiz o telefone tocar.

Falar no microfone não é a mesma coisa que ligar

No meu computador, sou eu que começo a conversa. O Whisper transforma minha fala em texto, a Edwiges responde e o Kokoro transforma a resposta em áudio. Whisper e Kokoro rodam localmente; isso não quer dizer que o modelo do Claude também esteja na minha GPU.

Quando o telefone toca, a situação muda. Quem atende pode estar no meio de qualquer coisa e precisa entender o recado nos primeiros segundos.

Eu queria uma mensagem curta, dizendo o que aconteceu e onde olhar. Nessa ligação, eu só ouço o áudio preparado pelo script. Para responder à Edwiges pelo telefone, precisaria montar também o caminho de volta.

Por que a ligação não usa o Kokoro?

O Kokoro vai continuar nas minhas conversas do dia a dia. Ele roda localmente, usando a minha GPU, então posso ter conversas longas sem consumir créditos da ElevenLabs. Tem o custo de energia e o tempo que eu dedico à manutenção, mas essa conversa local não usa os serviços da Twilio nem da ElevenLabs.

Para as ligações, escolhi a Twilio e a ElevenLabs porque eram os dois provedores que eu conhecia com as integrações de que precisava. A ElevenLabs transforma o texto do recado em um arquivo de áudio com a voz que escolhi. Depois, esse arquivo fica hospedado em um endereço que a Twilio consegue acessar. A Twilio faz a ligação e, quando eu atendo, toca o recado.

Assim, continuo usando o Kokoro nas conversas no meu computador e deixo a ElevenLabs e a Twilio para os avisos por telefone.

O caminho do áudio até o telefone

O primeiro passo foi escrever o recado e pedir à ElevenLabs para transformá-lo em um MP3. Até aí, eu tinha um arquivo na minha máquina. Faltava fazer esse arquivo chegar à ligação.

O texto vira MP3 na ElevenLabs, fica disponível por uma URL e é buscado pela Twilio para tocar na chamada telefônica.
O MP3 precisa estar acessível quando a Twilio for buscá-lo. Ter o arquivo só na minha máquina não basta.

Este é o pedido à API da ElevenLabs. A chave e o identificador da voz vêm de variáveis de ambiente:

curl --fail-with-body --silent --show-error \
  --output say.mp3 \
  --request POST \
  "https://api.elevenlabs.io/v1/text-to-speech/${ELEVENLABS_VOICE_ID}?output_format=mp3_44100_128" \
  --header "xi-api-key: ${ELEVENLABS_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{"text":"Alerta crítico no laboratório. Veja o WhatsApp.","model_id":"eleven_multilingual_v2"}'

No protótipo, subi o MP3 em uma hospedagem temporária e usei o endereço do arquivo na chamada. Para dizer à Twilio o que fazer depois que alguém atendesse, enviei instruções em TwiML, o formato que ela usa para controlar a ligação.

A instrução Play pede para buscar o áudio na URL e tocar:

# Exemplo didático: este POST cria uma chamada real e pode gerar cobrança.
# TWILIO_TO deve vir de um destino revisado e autorizado.
curl --fail-with-body --silent --show-error \
  --request POST \
  "https://api.twilio.com/2010-04-01/Accounts/${TWILIO_ACCOUNT_SID}/Calls.json" \
  --user "${TWILIO_ACCOUNT_SID}:${TWILIO_AUTH_TOKEN}" \
  --data-urlencode "To=${TWILIO_TO}" \
  --data-urlencode "From=${TWILIO_FROM}" \
  --data-urlencode 'Twiml=<Response><Play>https://example.com/say.mp3</Play></Response>'

Esses exemplos mostram a síntese e a chamada. Entre uma coisa e outra, ainda há o upload. Antes de ligar, é preciso conferir se veio um áudio válido, se o endereço funciona e se o destino foi autorizado. Se a API devolver um erro, o script precisa parar antes de publicar o arquivo.

O endereço example.com é só ilustrativo. Na chamada real, a URL precisa continuar válida até a Twilio buscar o arquivo. Se houver parâmetros nela, também é preciso escapá-los corretamente no XML.

O áudio ficou público, e isso me incomodou

A hospedagem temporária resolveu o teste, mas qualquer pessoa com aquela URL poderia baixar o recado.

O texto passa pela ElevenLabs, e o áudio fica na hospedagem e pode ser mantido em cache pela telefonia. Por isso, o recado precisa ser genérico. Nome de cliente, credencial e detalhe interno do ambiente ficam de fora.

Uma alternativa para evoluir isso é hospedar o arquivo sob meu controle, com uma URL assinada: um link que autoriza o acesso por um prazo definido. Eu ainda teria que implementar e testar essa alternativa.

O que ainda depende do meu computador

A Twilio faz a ligação nos servidores dela. Mas a Edwiges precisa conseguir executar o comando na minha máquina para pedir o áudio e a chamada. Se o computador desligar ou ficar sem internet antes disso, o aviso não sai.

Eu já consigo receber o recado longe do meu computador. Para receber também um aviso de que a própria máquina caiu, precisaria de outro serviço observando e disparando o alerta de fora dela.

O primeiro toque

Antes de usar esse comando nos alertas, eu precisava conferir se o texto virava um áudio compreensível e se esse áudio chegava ao telefone. Não queria descobrir que o recado estava baixo ou longo demais quando precisasse dele.

Comecei pelo modo de ensaio: o script gera o MP3, hospeda o arquivo e para antes de pedir a ligação à Twilio. Assim, eu podia ouvir a mensagem e conferir o endereço do áudio antes de ligar para alguém.

Mesmo sem discar, o ensaio já usa a geração de áudio da ElevenLabs, que pode consumir o saldo do plano ou gerar cobrança. Ao fazer a ligação real, entra também a cobrança de telefonia da Twilio, que depende do destino e da duração da chamada.

A mensagem de teste também precisava ser genérica, sem dados de cliente, credenciais ou detalhes internos do ambiente.

Depois, fiz a ligação de teste para minha mãe. Aí testei também o que o ensaio não cobria: a chamada pela Twilio e a reprodução do áudio no telefone.

Quanto isso custa de verdade

Na prática, esse laboratório me custou pouco. Para dar uma referência a quem quiser montar algo parecido, calculei um mês de uso leve com os preços oficiais consultados em 30/09/2026. Os valores estão em dólares e são uma simulação, não a reprodução da minha fatura.

Na Twilio, a conta combina o aluguel mensal do número com o consumo. Colocar saldo na conta é uma recarga; esse valor não vira uma assinatura a ser somada novamente às ligações e mensagens.

Para o exemplo, considerei um número local dos EUA habilitado para voz e SMS, com os avisos chegando a celulares no Brasil. Na ElevenLabs, seriam 10 gerações de 200 caracteres no modelo Multilingual v2: 10 × 200 = 2.000 caracteres no mês.

Simulação mensal: número Twilio US$1,15; 10 ligações US$0,663; 10 SMS US$0,599; ElevenLabs Starter US$6. Total aproximado US$8,41. Com Free permitido, US$2,41. Domínio finfy.me: US$1,99 no primeiro ano em promoção, à parte do total mensal. Valores e condições completos na descrição em texto abaixo.
Um mês de uso leve, com as quantidades do exemplo. O domínio é anual e fica fora desse total.

Fontes dos preços: número local na Twilio · ligações para o Brasil · SMS para o Brasil · planos da ElevenLabs. Consulta em 30/09/2026.

Ver os valores e a conta em texto

A conta fica em US$1,15 + US$0,663 + US$0,599 + US$6 = US$8,412, ou aproximadamente US$8,41 por mês para voz e telefonia nesse cenário.

Para testes pessoais não comerciais, o Free inclui 10.000 caracteres desse modelo pela API. Se esses forem os únicos usos, os 2.000 caracteres também cabem nele. Nesse caso, o Free substitui o Starter e o subtotal cai para US$2,41, respeitando as regras de uso não comercial e de atribuição ao compartilhar o áudio.

Dois detalhes mudam a conta: a Twilio arredonda a duração de cada chamada para cima, em minutos, e SMS é cobrado por segmento. Por isso, considerei um minuto faturado por ligação e mensagens que caibam em um segmento. Novas gerações de áudio, repetições e outros usos precisam entrar na soma também.

No primeiro ano, paguei US$1,99 pelo domínio finfy.me numa promoção. Esse custo fica separado da conta mensal. A renovação é anual e pode ter outro valor.

Agora a Edwiges liga. Mas quando ela deve ligar?

A Edwiges já podia usar o comando para me ligar. O próximo passo era fazer isso a partir dos alertas, sem que eu precisasse pedir cada chamada. Para isso, eu precisava definir para quem ela poderia ligar e em quais situações.

Esse é o assunto da próxima parte. Até mais, pessoal! 👋

Para entender as ferramentas