Call Center Complete Example
This section demonstrates building a complete customer service center with IVR, ACD queuing, skill group routing, monitoring, and CSAT.
Scenario Description
Company: An e-commerce customer service center, 50 agents, 3 skill groups
Skill Groups:
| Group | Agents | Skills | Responsibility |
|---|---|---|---|
| sales | 20 | sales, chinese | Pre-sales consultation |
| support | 20 | support, technical | After-sales technical support |
| vip | 10 | vip, sales, support, english | VIP customers |
Requirements:
- 400 hotline access, play IVR navigation first
- Press 1 for pre-sales, press 2 for after-sales
- VIP customers routed to VIP group with priority
- Support supervisor listen / whisper / barge
- Automatic CSAT survey after call ends
Step 1: Database
mysql -u root -p <<EOF
CREATE DATABASE rustpbx CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'rustpbx'@'%' IDENTIFIED BY 'CcP@ss2026';
GRANT ALL ON rustpbx.* TO 'rustpbx'@'%';
FLUSH PRIVILEGES;
EOF
Step 2: config.toml
http_addr = "0.0.0.0:8080"
database_url = "mysql://rustpbx:CcP@ss2026@dbhost:3306/rustpbx"
external_ip = "203.0.113.10"
[proxy]
addr = "0.0.0.0"
udp_port = 5060
modules = ["acl", "auth", "registrar", "call", "presence"]
media_proxy = "auto"
addons = ["cc"]
[proxy.cc]
autonomous_enabled = true
heartbeat_interval_secs = 5
heartbeat_timeout_count = 3
blind_transfer_enabled = true
consult_timeout_secs = 30
conference_on_transfer = true
voicemail_extension = "*97"
ivr_extension = "ivr"
[[proxy.cc.phone.break_types]]
id = "lunch"
label_zh = "午休"
label_en = "Lunch"
[[proxy.cc.phone.break_types]]
id = "training"
label_zh = "培训"
label_en = "Training"
[[proxy.cc.phone.break_types]]
id = "meeting"
label_zh = "会议"
label_en = "Meeting"
[console]
session_secret = "cc-console-secret-2026"
Step 3: Carrier Trunk
config/trunks/carrier.toml:
[[trunk]]
name = "carrier-inbound"
direction = "inbound"
inbound_hosts = ["198.51.100.10"]
codec = ["pcmu", "pcma"]
max_calls = 100
Step 4: Create Extensions
Batch create 50 extensions (1001-1050) in the console under Extensions:
- Randomly generated passwords
- Registered to RustPBX
Step 5: Create Skill Groups
Call Center → Skill Groups → New:
| ID | Name | Skills |
|---|---|---|
| sales | Pre-sales Team | sales, chinese |
| support | After-sales Team | support, technical |
| vip | VIP Team | vip, sales, support, english |
Or create config/cc/skill_groups.toml:
[[skill_group]]
id = "sales"
name = "Pre-sales Team"
skills = ["sales", "chinese"]
[[skill_group]]
id = "support"
name = "After-sales Team"
skills = ["support", "technical"]
[[skill_group]]
id = "vip"
name = "VIP Team"
skills = ["vip", "sales", "support", "english"]
Step 6: Create Agents
Call Center → Agents → Batch Create:
| Agent ID | Extension | Skill Group | Max Concurrent |
|---|---|---|---|
| agent-001 ~ agent-020 | 1001-1020 | sales | 1 |
| agent-021 ~ agent-040 | 1021-1040 | support | 1 |
| agent-041 ~ agent-050 | 1041-1050 | vip | 2 |
Step 7: Configure Queues
config/queue/sales_queue.toml:
[[queue]]
name = "sales-queue"
strategy = "parallel"
max_wait_secs = 300
max_size = 50
moh = "default"
[queue.agent_match]
skill_group = "sales"
[queue.no_answer]
action = "voicemail"
config/queue/support_queue.toml:
[[queue]]
name = "support-queue"
strategy = "parallel"
max_wait_secs = 300
max_size = 50
moh = "default"
[queue.agent_match]
skill_group = "support"
[queue.no_answer]
action = "voicemail"
config/queue/vip_queue.toml:
[[queue]]
name = "vip-queue"
strategy = "parallel"
max_wait_secs = 60
max_size = 20
moh = "default"
[queue.agent_match]
skill_group = "vip"
[queue.no_answer]
action = "fallback_skill"
fallback_skill_group = "sales"
Step 8: Configure IVR
Use the IVR Editor or manually create IVR configuration:
config/ivr/main_ivr.toml (simplified):
[[ivr]]
name = "main-ivr"
greeting = "welcome"
timeout = 10
max_retries = 3
[[ivr.menu]]
key = "1"
action = "queue"
target = "sales-queue"
[[ivr.menu]]
key = "2"
action = "queue"
target = "support-queue"
[[ivr.menu]]
key = "0"
action = "queue"
target = "vip-queue"
Step 9: Routing Configuration
config/routes/inbound.toml:
[[route]]
name = "400-hotline"
action = "application"
application = "ivr:main-ivr"
[route.match]
to_user = "^4001234567$"
Step 10: ACD Policy
Via the console Call Center → ACD Configuration:
[acd]
enabled = true
default_policy = "default"
[acd.policies.default]
name = "default"
[acd.policies.default.strategy]
strategy_type = "longest_idle"
max_concurrent_calls = 1
[acd.policies.default.priority]
wait_time_weight = 1.5
fifo_within_same_priority = true
[acd.policies.default.priority.vip_bonus]
vip = 100
[acd.policies.default.overflow]
triggers = [
{ type = "timeout", value = 120, action = "overflow" },
{ type = "queue_length", value = 50, action = "overflow" },
]
chain = ["voicemail"]
Step 11: Launch
docker run -d --name cc-pbx \
-v $(pwd)/config.toml:/app/config.toml \
-v $(pwd)/config:/app/config \
-p 8080:8080 -p 5060:5060/udp \
docker.cnb.cool/miuda.ai/rustpbx:latest
Step 12: Verification
12.1 Agents Go Online
Agents visit /cc/phone, log in with their extension number, and set status to Idle.
12.2 Test Inbound Call
Dial the 400 hotline:
- Hear IVR welcome greeting
- Press 1 → enter sales-queue
- ACD assigns idle agent → agent rings → answer
12.3 Test Monitoring
Admin finds an active call in Call Center → Real-time Monitoring and clicks Listen.
12.4 Test CSAT
Call ends → agent hangs up → caller hears satisfaction prompt → presses key to rate → CDR records the rating
12.5 Test VIP Routing
VIP customer dials 400 → presses 0 → enters vip-queue → priority bonus (+100) → queued ahead of regular callers
Step 13: Daily Operations
| Task | Frequency | Location |
|---|---|---|
| Check Dashboard | Daily | CC → Dashboard |
| Review SLA | Daily | CC → Real-time Monitoring |
| Review alerts | Real-time | CC → Alerts |
| Agent reports | Weekly | CC → Reports |
| Call reports | Weekly | CC → Reports |
| CSAT analysis | Monthly | CC → Reports |
| Skill group adjustments | As needed | CC → Skill Groups |