Implements a Pion Go B2BUA media server sidecar that sits between Meta's WhatsApp Cloud API and the agent's browser, enabling call persistence across page reloads, server-side recording, multi-participant support, audio injection, and AI integration readiness. Go Media Server (enterprise/media-server/): - Pion WebRTC v4 B2BUA with Peer A (Meta) and Peer B (Agent) connections - Real-time OGG/Opus recording with crash recovery - Audio bridge with multi-peer fan-out and AudioConsumer plugin interface - Audio injection from OGG files with loop support for hold music - Session manager with graceful shutdown and orphaned recording recovery - HTTP API with Bearer token auth, health checks, and metrics Rails Integration: - Whatsapp::MediaServerClient HTTP client for Go sidecar communication - Dual-mode CallService: legacy browser-direct and server-relay paths - Media server callback controller for agent disconnect/recording/terminate - CallRecordingFetchJob: downloads OGG from Go server to ActiveStorage/S3 - CallCleanupJob: sweeps stale ringing and in-progress calls - New endpoints: active, agent_answer, reconnect, join, play_audio - DB migration: media_session_id column with indexes Frontend: - Dual-mode composable auto-detecting legacy vs server-relay - handleAgentOffer() for receiving SDP from media server - useCallReconnection composable for page reload recovery - Removed terminateCallOnUnload in server-relay mode - Simplified outbound call flow in ConversationHeader - New ActionCable event: whatsapp_call.agent_offer Documentation: - Server-side WebRTC architecture spec (1505 lines) - Implementation plan with 119 trackable checklist items - Feature spec, PR breakdown, and relay architecture docs
91 lines
2.3 KiB
YAML
91 lines
2.3 KiB
YAML
version: '3'
|
|
|
|
services:
|
|
base: &base
|
|
image: chatwoot/chatwoot:latest
|
|
env_file: .env ## Change this file for customized env variables
|
|
volumes:
|
|
- storage_data:/app/storage
|
|
|
|
rails:
|
|
<<: *base
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
ports:
|
|
- '127.0.0.1:3000:3000'
|
|
environment:
|
|
- NODE_ENV=production
|
|
- RAILS_ENV=production
|
|
- INSTALLATION_ENV=docker
|
|
entrypoint: docker/entrypoints/rails.sh
|
|
command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0']
|
|
restart: always
|
|
|
|
sidekiq:
|
|
<<: *base
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
environment:
|
|
- NODE_ENV=production
|
|
- RAILS_ENV=production
|
|
- INSTALLATION_ENV=docker
|
|
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
|
restart: always
|
|
|
|
postgres:
|
|
image: pgvector/pgvector:pg16
|
|
restart: always
|
|
ports:
|
|
- '127.0.0.1:5432:5432'
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
environment:
|
|
- POSTGRES_DB=chatwoot
|
|
- POSTGRES_USER=postgres
|
|
# Please provide your own password.
|
|
- POSTGRES_PASSWORD=
|
|
|
|
redis:
|
|
image: redis:alpine
|
|
restart: always
|
|
command: ["sh", "-c", "redis-server --requirepass \"$REDIS_PASSWORD\""]
|
|
env_file: .env
|
|
volumes:
|
|
- redis_data:/data
|
|
ports:
|
|
- '127.0.0.1:6379:6379'
|
|
|
|
# Optional: WhatsApp Calling media server (server-side WebRTC relay)
|
|
# Uncomment to enable call persistence across page reloads and server-side recording.
|
|
# media-server:
|
|
# image: chatwoot/media-server:latest
|
|
# env_file: .env
|
|
# ports:
|
|
# - '4000:4000'
|
|
# - '10000-10100:10000-10100/udp'
|
|
# environment:
|
|
# - AUTH_TOKEN=${MEDIA_SERVER_AUTH_TOKEN}
|
|
# - RAILS_CALLBACK_URL=http://rails:3000
|
|
# - RECORDINGS_DIR=/recordings
|
|
# - LOG_LEVEL=info
|
|
# - UDP_PORT_MIN=10000
|
|
# - UDP_PORT_MAX=10100
|
|
# - PUBLIC_IP=${MEDIA_SERVER_PUBLIC_IP}
|
|
# - STUN_SERVERS=stun:stun.l.google.com:19302
|
|
# volumes:
|
|
# - media_recordings:/recordings
|
|
# restart: always
|
|
# healthcheck:
|
|
# test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:4000/health']
|
|
# interval: 10s
|
|
# timeout: 5s
|
|
# retries: 3
|
|
|
|
volumes:
|
|
storage_data:
|
|
postgres_data:
|
|
redis_data:
|
|
# media_recordings:
|