Skip to content

Customer Service

The Customer Service plugin provides 1v1 real-time audio/video customer service capabilities for Monibuca V6. It is suitable for online customer support, remote consultation, after-sales support, and similar scenarios.

  • 1v1 calls: Each session is limited to 2 participants (agent + customer), based on Room Service’s max_users: 2 constraint
  • No-login customer side: Customers can enter the call directly via link without account registration
  • Agent management: Supports session assignment, transfer, and statistics
  • Audio mixing: Agent side can mix local audio files into the stream (e.g., background music, notification sounds)
  • Satisfaction rating: Customers can provide star ratings after the call ends
  • Admin dashboard: Complete session management interface with session creation, user link/QR code generation
Cargo.toml
features = ["customer-service"]
# Customer service depends on Room Service
# The room feature is automatically enabled
graph TB
subgraph CS["CustomerService Plugin"]
SM["SessionManager<br/>Session management (DashMap)"]
HTTP["HTTP API<br/>/customer-service/*"]
Signal["WebSocket Signaling<br/>AcceptCall / EndCall / Transfer"]
end
subgraph RS["Room Service (Engine Built-in)"]
Room["Room Management<br/>max_users: 2"]
WS["WebSocket<br/>Signaling"]
end
subgraph Client["Clients"]
Agent["Agent Side<br/>Account login"]
Customer["Customer Side<br/>No login required"]
end
CS -->|"register_callbacks<br/>RoomType::CustomerService"| RS
HTTP --> SM
Agent -->|"WebRTC (WHIP)"| Room
Customer -->|"WebRTC (WHIP)"| Room
Agent <-->|"WebSocket"| WS
Customer <-->|"WebSocket"| WS
Waiting → Active → Ended
StatusDescription
WaitingSession created, waiting for agent/customer to join
ActiveBoth parties have joined, call in progress
EndedCall has ended

All endpoints are prefixed with /customer-service/.

MethodPathDescription
GET/sessionsGet session list
GET/sessions/{id}Get session details
POST/sessionsCreate new session
DELETE/sessions/{id}Close/delete session
POST/sessions/{id}/assignAssign agent
GET/statsGet statistics
Terminal window
curl -X POST http://localhost:8080/customer-service/sessions \
-H "Content-Type: application/json" \
-d '{
"title": "After-sales inquiry",
"customer_name": "John"
}'

Response:

{
"code": 0,
"data": {
"id": "cs_abc123",
"title": "After-sales inquiry",
"customer_id": "cust_001",
"customer_name": "John",
"status": "Waiting",
"created_at": "2024-01-15T10:30:00Z"
}
}
Terminal window
curl -X POST http://localhost:8080/customer-service/sessions/cs_abc123/assign \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent_001",
"agent_name": "Agent Wang"
}'
Terminal window
curl http://localhost:8080/customer-service/stats

Response:

{
"code": 0,
"data": {
"total_sessions": 156,
"active_sessions": 3,
"waiting_sessions": 2,
"ended_sessions": 151
}
}

Customer service calls use dedicated WebSocket signaling, which is forwarded to the plugin through the Room Service’s on_message callback.

ActionDirectionDescription
accept_callC→SAgent accepts the call
end_callC→SEither party hangs up
transfer_callC→SAgent transfers to another agent
hold_callC→SHold the call
resume_callC→SResume the call
call_acceptedS→CNotify the other party that the call has been answered
call_endedS→CNotify that the call has ended
call_transferredS→CNotify that the call has been transferred
{
"action": "accept_call",
"room_id": "customer-service/cs_abc123",
"user_id": "agent_001"
}
customer_service:
max_sessions: 1000 # Maximum concurrent sessions
session_timeout: 3600 # Session timeout (seconds), default 1 hour
enable_recording: false # Whether to enable call recording

Clients join customer service calls via the standard Room WebSocket connection:

ws://host:port/room?type=customer_service

The room ID format is customer-service/{session_id}, using a prefix to distinguish different room types.


The customer service demo is built on Monibuca Web-SDK’s Web Components:

<!-- Room container -->
<mb-room id="room"></mb-room>
<!-- Local publisher -->
<mb-publisher id="publisher"></mb-publisher>
<!-- Remote subscriber -->
<mb-subscriber id="subscriber"></mb-subscriber>
const room = document.getElementById('room') as MbRoom;
const publisher = document.getElementById('publisher') as MbPublisher;
// Set up WebSocket connection
room.setAttribute('ws-url', 'ws://localhost:8080/room?type=customer_service');
room.setAttribute('room-id', 'customer-service/session_001');
// Start publishing
await publisher.startCapture({ audio: true, video: true });
await publisher.startPublish();

The agent side supports mixing local audio files into the stream, such as background music or waiting notification sounds:

const publisher = document.getElementById('publisher') as MbPublisher;
// Mix in a local audio file
publisher.mixAudio('bgm', '/audio/background-music.mp3', 0.3);
// Adjust mix volume (0.0 ~ 1.0)
publisher.setMixVolume('bgm', 0.5);
// Remove mix source
publisher.unmixAudio('bgm');

Mixing principle:

graph LR
Mic["Microphone<br/>MediaStream"] --> GainA["GainNode<br/>Mic volume"]
BGM["Audio File<br/>MediaElement"] --> GainB["GainNode<br/>Mix volume"]
GainA --> Dest["Destination<br/>Combined output"]
GainB --> Dest
Dest --> WHIP["WHIPClient<br/>WebRTC publish"]

Internally, the SDK uses the Web Audio API’s AudioContext to mix multiple audio sources (microphone + mix files) through GainNode into a single MediaStreamAudioDestinationNode, which is then output to the WebRTC stream.

It is recommended to use a state machine to manage the call flow:

type CallStage = 'waiting' | 'connecting' | 'connected' | 'ended';
// waiting → Waiting for the other party to join (display waiting UI, pulse animation)
// connecting → WebRTC connection being established
// connected → Call in progress (display video, timer, control bar)
// ended → Call ended (display call duration, satisfaction rating)

The customer service module provides a complete management interface in the Admin dashboard.

  • Statistics cards: Total sessions, active calls, waiting for connection
  • Session list: Supports status filtering, search, and batch operations
  • Create session: Enter title and description, auto-assign agent
  • Assign agent: Manually assign a session to a specific agent
  • Generate link: Generate dedicated entry links and QR codes for customers/agents

The Admin embeds a 1v1 call page, allowing administrators to test calls directly:

  • Side-by-side video layout
  • Microphone/camera controls
  • Text chat panel
  • Call statistics

Customer service room data is collected through the Room Service’s reporting system and automatically filtered by the customer-service/ prefix for display in the Admin.


The complete customer service demo is located at web-sdk/packages/demo/customer-service/:

customer-service/
├── src/
│ ├── pages/
│ │ ├── Lobby/index.tsx # Entry: role selection, session input
│ │ └── CallRoom/index.tsx # Call: 1v1 video, control bar, chat
│ ├── services/api.ts # API wrapper
│ └── types/index.ts # Type definitions
├── package.json # port: 5476
└── vite.config.ts
Terminal window
cd web-sdk/packages/demo/customer-service
pnpm install
pnpm dev
# Visit http://localhost:5476

Customers enter the call directly via a parameterized link without logging in:

http://localhost:5476?session=cs_abc123&role=customer

Agents need to log in with credentials:

http://localhost:5476?session=cs_abc123&role=agent

The demo automatically detects device type. On mobile devices:

  • Top-bottom split video layout
  • Fixed bottom control bar (with safe area adaptation)
  • Touch-optimized interactions