Softphone WebRTC dentro do Zendesk: como transformei o ticket na própria estação de trabalho do atendente.

Antes de escrever a primeira linha, fiz um inventário de três implementações de telefonia dentro de helpdesk — duas já existiam — e comparei capacidade por capacidade, não por volume de código.

Minha primeira hipótese era que eu teria de escolher uma delas e reescrever o resto. Estava errado. A tabela mostrou duas coisas:

  1. A implementação que só observava a central já fazia o registro muito bem — identificação do cliente, ticket, notas, gravação, transcrição. O que faltava nela era voz.
  2. A implementação que falava só existia enquanto houvesse um ticket aberto na aba. Boa para ligar, frágil para receber.

A decisão de arquitetura saiu da tabela, não da preferência: não trocar uma metade pela outra — costurar a voz dentro do painel que já observava. A lista de capacidades perdidas no caminho ficou vazia.


📞 Uma ligação recebida, antes e depois

Softphone embutido no painel lateral do ticket, dentro do helpdesk
O softphone embutido no painel lateral do ticket: o atendente não troca de janela para falar com o cliente
MomentoSem o softphoneCom o softphone
O telefone tocaAviso num aplicativo separado, fora do helpdesk.Aviso dentro do helpdesk, com o nome de quem liga.
Quem é o cliente?Ouve o nome e procura o cadastro à mão.O cadastro já está na tela — número resolvido em três formatos.
Não tem cadastroAbrir outra aba, criar o contato, voltar.Contato e organização criados dali mesmo.
AtenderDiscador à parte: segunda janela, segundo foco.Um botão ao lado do ticket. Áudio no próprio navegador.
Durante a conversaMudo, espera e teclado no outro aplicativo.Tudo ao lado do ticket.
TransferirCega, sem falar antes com quem recebe.Cega ou assistida.
Caiu ruimFica a impressão: “estava ruim hoje”.Perda e jitter medidos, em quatro barras, durante a chamada.
DesligouO atendente digita de memória.Nota automática: status, durações e gravação anexada.
O que foi ditoSó ouvindo a gravação inteira de novo.Transcrição e resumo por IA no próprio ticket.
Perdeu a chamadaDescobre no relatório, no dia seguinte.Aviso persistente, sem duplicar se a mesma ligação insistir.

🧩 O que o software faz, em 6 blocos

  • 1. Telefonia completa no navegador: discar com teclado e histórico clicável, atender, recusar, mudo, espera, teclado numérico durante a chamada (para navegar em uras de terceiros), transferência cega e assistida. Uma segunda chamada que chegue durante a primeira é avisada sem roubar a tela.
  • 2. Gravação comandada na central: a gravação acontece onde ela é confiável — no PABX, não no navegador. O botão só fica disponível se o ramal daquele atendente tiver permissão, e o estado vem do evento da própria central.
  • 3. Qualidade medida, não sentida: perda de pacotes e jitter em quatro barras, atualizadas durante a conversa e registradas junto da chamada. Quando o cliente reclama que “ficou ruim”, existe número.
  • 4. O ticket se escreve sozinho: identificação pelo telefone em três formatos, criação de contato e organização, vínculo com ticket existente ou criação de um novo, nota de início e de encerramento com status e durações, gravação anexada com player nativo, transcrição e resumo por IA.
  • 5. Disponível antes do primeiro clique: o registro de telefonia sobe num processo em segundo plano assim que o helpdesk abre. Há eleição de dono entre as abas — o mesmo ramal nunca registra duas vezes — e uma trava que impede o registro quando o microfone está bloqueado, com escape manual.
  • 6. Erros em português de gente: 20 códigos de erro do SDK de voz traduzidos para causa e ação. O operador lê “o plano do SDK está desabilitado na central”, não um número.
Chamada em andamento com cronômetro, gravação e qualidade medida
Em conversa: cronômetro, gravação comandada na central e qualidade da ligação em quatro barras

⚖️ Três abordagens para o mesmo problema

A tabela que decidiu a arquitetura, resumida. As três resolvem o mesmo problema por caminhos diferentes:

CapacidadePainel que observaSoftphone só no ticketEsta abordagem
Áudio no próprio navegador❌ discador externo
Funciona sem ticket aberto
Eventos da central em tempo real
Cliente na tela antes do “alô”🟡 depende de onde o agente olha
Teclado numérico na chamada
Transferência assistida
Gravação por permissão do ramal
Qualidade medida na tela
Registro ativo antes do 1º clique
Transcrição e resumo por IA

A lição que ficou: comparar por volume de código teria dado o veredito oposto. Comparar por capacidade mostrou que a base certa era a que parecia menor.

🏗️ Um código, três casas

  • 1. Dentro do helpdesk: o aplicativo instalado tem 44 KB e não contém a lógica do softphone — ele carrega a aplicação do backend em tempo de execução. Uma melhoria chega ao atendente com um F5, sem reinstalar e sem janela de manutenção.
  • 2. No navegador: a mesma aplicação aberta direto, para operação avulsa.
  • 3. Como aplicativo de mesa: janela nativa, bandeja do sistema e notificação do sistema operacional. O frontend detecta o ambiente sozinho e esconde os controles que não fazem sentido nele.

Duas fontes de verdade, com fronteira escrita. O SDK de voz manda enquanto a chamada está viva — quem toca, quem atende, quanto tempo faz. A API da central manda depois que ela termina — status oficial, duração faturável, gravação em arquivo, transcrição.

Cada uma chama a mesma ligação por um identificador diferente, então existe uma camada de correlação por número e janela de tempo — com uma rede de segurança: se o registro oficial não chegar em 45 segundos, a nota sai com os números do navegador e declara a origem. Número sem procedência declarada é número que alguém vai usar errado depois.

Discador com teclado, histórico e ramal registrado
O mesmo discador roda embutido no helpdesk, no navegador e como aplicativo de mesa

🖼️ As telas

🔒 Código-fonte e Painel Git próprio

O código-fonte integral e o histórico de commits estão versionados em infraestrutura própria — uma plataforma de hospedagem Git que eu mesmo construí e que também está no portfólio:

https://git.programandosolucoes.com.br/git/

Nada de GitHub, GitLab ou Bitbucket no caminho: repositórios, chaves SSH, permissões por usuário, pull requests e política de branch rodam em servidor próprio. Ver o projeto do Painel Git no portfólio →

Nota: este repositório é privado e sob acordo de confidencialidade com o cliente — por isso o endereço do repositório em si não é publicado. Caso deseje acesso para avaliação técnica ou parceria, entre em contato diretamente.

🖼️ Sobre as telas deste artigo

Projeto executado sob acordo de confidencialidade. As telas deste artigo estão descaracterizadas: marca, cores e dados de exemplo foram substituídos — a troca é feita por injeção no instante da captura, não em editor de imagem, para que a aparência do produto real nunca vaze por descuido de recorte.

Nota: código privado. Converso sobre a arquitetura e as decisões em detalhe — para avaliação técnica ou parceria, entre em contato diretamente.

Carlos Alberto — carlosalberto4ti@gmail.com · +55 11 2615-2880