Skip to content

**feat(gows): integração VoIP com gows-plus — API REST, WebRTC e eventos de lifecycle**#1

Open
mbarizao wants to merge 1 commit into
devlikeapro:masterfrom
mbarizao:feature/voip
Open

**feat(gows): integração VoIP com gows-plus — API REST, WebRTC e eventos de lifecycle**#1
mbarizao wants to merge 1 commit into
devlikeapro:masterfrom
mbarizao:feature/voip

Conversation

@mbarizao

@mbarizao mbarizao commented Jun 24, 2026

Copy link
Copy Markdown

Summary

Esta PR adiciona suporte a chamadas de voz/vídeo (VoIP) no engine GOWS, integrando o WAHA com o binário estendido gows-plus via gRPC. O fluxo segue o modelo do WaCalls: signaling WhatsApp no motor Go + ponte WebRTC Opus no browser para áudio bidirecional.

A implementação no WAHA expõe endpoints REST compatíveis com o contrato do WaCalls, emite eventos de lifecycle via WebSocket/webhooks e inclui um stack Docker de teste (docker-compose.gows-test.yaml) para validar o fluxo ponta a ponta.


Inspiração: WaCalls

O design foi inspirado no repositório WaCalls, que demonstra como:

  • Receber e processar eventos de signaling (CallOffer, CallAccept, CallTransport, etc.)
  • Conectar aos relays SCTP do WhatsApp para mídia Opus
  • Expor uma ponte WebRTC (POST /calls/{id}/webrtc) para o browser enviar/receber áudio

Esta PR adapta esse modelo ao ecossistema WAHA: API NestJS, eventos call.*, sessões GOWS e cliente gRPC dedicado (GowsCallsClient).


O que foi implementado

API REST (CallsController)

Método Endpoint Descrição
POST /api/{session}/calls Inicia chamada outbound (áudio/vídeo)
GET /api/{session}/calls/state Estado da chamada ativa (active, call_id, direction, status)
POST /api/{session}/calls/{id}/accept Aceita chamada inbound (X-Client-Id opcional para claim multi-cliente)
POST /api/{session}/calls/{id}/reject Rejeita por ID (compatível WaCalls; from opcional se houver state)
POST /api/{session}/calls/reject Rejeita com from + id no body
POST /api/{session}/calls/{id}/webrtc Troca SDP offer/answer para bridge WebRTC no browser
DELETE /api/{session}/calls/{id} Encerra chamada ativa

DTOs documentados no Swagger (calls.dto.ts).

Cliente gRPC GOWS (GowsCallsClient)

Encapsula as RPCs do gows-plus:

  • StartCall, AcceptCall, RejectCall, EndCall
  • ExchangeCallWebRTC, GetCallState

Sessão GOWS (session.gows.core.ts)

  • Métodos de chamada na sessão (startCall, acceptCall, endCall, exchangeCallWebRTC, getCallState)
  • Eventos de lifecycle emitidos pelo gows-plus mapeados para o WAHA:
    • call.received, call.ringing, call.connecting
    • call.accepted, call.active, call.ended, call.rejected
  • Merge de CallOffer bruto + lifecycle do motor (dedupe por call_id)
  • Resolução de caller via CallCreatorAlt / caller_pn (número real em vez de só @lid)
  • Filtro de CallReject em dispositivo vinculado (rejected_elsewhere)
  • Inicialização do CallManager em eventos de chamada (corrige call.received antes do primeiro StartCall)

Infraestrutura

  • GowsSubprocess: LD_LIBRARY_PATH apontando para native/ do gows-plus (libopus)
  • docker-compose.gows-test.yaml: stack de teste WAHA + Postgres + build do gows-plus com symlinks libopus
  • GET /calls/state: header Cache-Control: no-store (evita 304 em polling do dashboard)

Contratos e webhooks

  • Novos valores em WAHAEvents para o ciclo completo da chamada
  • Payloads de webhook para os novos eventos (webhooks.dto.ts)

Arquitetura (visão geral)

Browser (WebRTC Opus)
        ↕ POST /calls/{id}/webrtc
   WAHA (NestJS)
        ↕ gRPC
   gows-plus (Go)
        ↕ SCTP relay + SRTP
   WhatsApp

O WAHA não processa mídia diretamente: faz signaling HTTP/gRPC e repassa eventos. O áudio flui browser ↔ gows-plus ↔ relay WhatsApp.


Dependências

  • Requer gows-plus (fork/extend do GOWS) com RPCs de VoIP no gows.proto
  • Engine da sessão: GOWS
  • Para áudio no browser: cliente WebRTC que chame /webrtc após accept ou start

Test plan

  • Subir stack: docker compose -f docker-compose.gows-test.yaml up -d --build
  • Sessão GOWS pareada e WORKING
  • Outbound: POST /api/{session}/callsPOST .../webrtccall.active → áudio OK
  • Inbound: receber call.receivedPOST .../acceptPOST .../webrtccall.active
  • GET /api/{session}/calls/state retorna active: true durante a chamada
  • DELETE /api/{session}/calls/{id} emite call.ended
  • WebSocket: eventos call.* chegam ao cliente inscrito
  • Rejeição em dispositivo vinculado não dispara call.rejected falso no dashboard

Notas

  • Compatibilidade de rotas alinhada ao WaCalls (/accept, /webrtc, /reject por ID)
  • O dashboard VoIP (waha-hub) é opcional e vive em repositório separado; esta PR cobre apenas o backend WAHA + stack de teste
  • Chamadas de grupo e vídeo no browser ainda dependem de evolução no gows-plus

…y parsing.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant