DEV Community

Moisi Trungu
Moisi Trungu

Posted on Originally published at flixzone.icu

How to Configure ViciDial Closer Campaigns & In-Groups

How to Configure ViciDial Closer Campaigns & In-Groups

Master the complete process of setting up closer campaigns and in-groups in ViciDial, from database configuration through agent assignment and real-time monitoring.

Prerequisites

Before proceeding with closer campaign and in-group configuration, ensure you have:

  • ViciDial installation (3.14+ recommended) with working Asterisk (16+)
  • Database access: Direct MySQL/MariaDB access to the asterisk database
  • Admin credentials: Access to /vicidial/admin.php with administrator role
  • Asterisk CLI access: Ability to run asterisk -rx commands
  • Existing dialplans: At least one active dialer campaign configured
  • User accounts: Multiple agents already created in ViciDial system
  • In-group defined: A primary in-group created before closer assignment
  • SSH/Shell access to ViciDial server with sudo privileges

Understanding Closer Campaigns vs In-Groups

What Are Closer Campaigns?

Closer campaigns are ViciDial's mechanism for transferring live inbound calls or callbacks to specific agents who specialize in closing sales. Unlike dialer campaigns that push calls outbound, closer campaigns pull inbound calls into a queue for assignment to available agents.

Key characteristics:

  • Receive transferred calls from dialer campaigns or direct phone numbers
  • Queue calls until agent availability
  • Track transfer times and call dispositions separately
  • Support multiple in-groups within one closer campaign
  • Integrate with DNC (Do Not Call) lists and custom call rules

What Are In-Groups?

In-groups are the actual agent queues where calls wait for assignment. A closer campaign may have multiple in-groups (e.g., "Sales", "Support", "Escalations"), each with distinct:

  • Member agents with individual priorities
  • Call handling rules and routing logic
  • Recording preferences
  • Custom CID masking
  • Hold music and announcements

The relationship: Closer Campaign contains In-Groups containing Agents

Part 1: Create the Closer Campaign via Web UI

Step 1.1: Access Campaign Configuration

  1. Log into /vicidial/admin.php with administrator account
  2. Navigate: Admin → Campaigns → Add New Campaign
  3. Select Campaign Type: "Closer"
  4. Fill in campaign details:
Field Example Value Notes
Campaign ID CLOSER_SALES Uppercase, no spaces, 2-20 chars
Campaign Name Sales Closer Campaign Human-readable name
Active YES Enable immediately
Outbound CID 18005551234 Caller ID for transfers
Outbound CID Name Sales Dept Display name (optional)
Phone Number 18005551000 DID for external transfers
Call Time Zone America/Chicago Agent's timezone
Use Asterisk YES Required for call routing

Step 1.2: Configure Callback and Transfer Settings

In the same campaign creation form:

Callback Auto Hold Minutes:          5
Callback Auto Dial:                  YES
Campaigns to receive from:           DIALER_SALES,DIALER_LEADS
Transfer Timeout Seconds:            45
Voicemail Extension:                 9999
Call Recording:                      ALWAYS
Recording Call Display Name:         CLOSER_SALES
Lead ID Prefix:                      CS-
Enter fullscreen mode Exit fullscreen mode

Critical setting: Leave "Closer Dial Campaign" BLANK (this is for callbacks originated from closer agents, not for receiving transfers)

Step 1.3: Save and Verify

Click SUBMIT. ViciDial will:

  1. Create campaign record in vicidial_campaigns table
  2. Create campaign contexts in /etc/asterisk/extensions-vicidial.conf
  3. Generate default dialplan extensions

Verify creation:

mysql -u root -p asterisk -e "SELECT campaign_id, campaign_name, campaign_type, active FROM vicidial_campaigns WHERE campaign_id='CLOSER_SALES';"
Enter fullscreen mode Exit fullscreen mode

Expected output:

| CLOSER_SALES | Sales Closer Campaign | CLOSER | Y |
Enter fullscreen mode Exit fullscreen mode

Part 2: Create In-Groups Within the Closer Campaign

Step 2.1: In-Group Fundamentals

In-groups are the actual call queues. You must create at least one in-group per closer campaign. Most production environments have 2-4 in-groups:

  • Primary in-group: Handles all standard transfers
  • Overflow in-group: Secondary queue when primary is full
  • VIP in-group: Dedicated high-value customer queue
  • Escalation in-group: Complex issues requiring senior agents

Step 2.2: Create In-Group via Database

While ViciDial admin UI has in-group creation, direct database insertion is faster for bulk setup:

INSERT INTO vicidial_ingroups (
  ingroup_id,
  campaign_id,
  ingroup_name,
  description,
  active,
  callback_grp,
  phone_number,
  voicemail_ext,
  hold_music,
  recording_call_display_name,
  call_timeout,
  call_priority,
  full_set_queue_exten,
  customer_greeting,
  agent_greeting,
  in_group_digits
) VALUES (
  'CLOSER_SALES_MAIN',
  'CLOSER_SALES',
  'Sales Main Queue',
  'Primary in-group for sales closer campaign',
  'Y',
  'Y',
  '18005551000',
  '9999',
  'default',
  'CLOSER_SALES_MAIN',
  '120',
  '1',
  '1',
  'Thanks for calling. A representative will be with you shortly.',
  'Thank you for calling. Please give me one moment while I retrieve your information.',
  ''
);
Enter fullscreen mode Exit fullscreen mode

Key fields explanation:

  • ingroup_id: Unique identifier across system (24 chars max)
  • callback_grp: Allow agents to callback? Set 'Y' for closer queues
  • call_timeout: Seconds before call abandons from queue (120-300 typical)
  • call_priority: Lower number = higher priority (1-5 range)
  • full_set_queue_exten: Extension when queue full (usually extension 1)
  • recording_call_display_name: Identifies recording in playback system

Step 2.3: Create Secondary In-Group (Overflow)

INSERT INTO vicidial_ingroups (
  ingroup_id,
  campaign_id,
  ingroup_name,
  description,
  active,
  callback_grp,
  phone_number,
  voicemail_ext,
  hold_music,
  call_timeout,
  call_priority,
  full_set_queue_exten
) VALUES (
  'CLOSER_SALES_OVERFLOW',
  'CLOSER_SALES',
  'Sales Overflow Queue',
  'Overflow for sales closer campaign',
  'Y',
  'Y',
  '18005551001',
  '9999',
  'default',
  '150',
  '2',
  '1'
);
Enter fullscreen mode Exit fullscreen mode

Step 2.4: Verify In-Group Creation

mysql -u root -p asterisk -e "SELECT ingroup_id, campaign_id, ingroup_name, active, call_timeout FROM vicidial_ingroups WHERE campaign_id='CLOSER_SALES';"
Enter fullscreen mode Exit fullscreen mode

Expected:

| CLOSER_SALES_MAIN      | CLOSER_SALES | Sales Main Queue    | Y | 120 |
| CLOSER_SALES_OVERFLOW  | CLOSER_SALES | Sales Overflow Queue| Y | 150 |
Enter fullscreen mode Exit fullscreen mode

Part 3: Assign Agents to In-Groups

Step 3.1: Add Agent Memberships

Agents must be explicitly assigned to in-groups via the vicidial_ingroup_agents table. Each agent can belong to multiple in-groups with different priorities and statuses:

INSERT INTO vicidial_ingroup_agents (
  ingroup_id,
  user_id,
  agent_priority,
  lead_id,
  agent_status,
  closer_flag
) VALUES
  ('CLOSER_SALES_MAIN', 'agent001', 1, '0', 'ACTIVE', 'Y'),
  ('CLOSER_SALES_MAIN', 'agent002', 2, '0', 'ACTIVE', 'Y'),
  ('CLOSER_SALES_MAIN', 'agent003', 3, '0', 'ACTIVE', 'Y'),
  ('CLOSER_SALES_OVERFLOW', 'agent004', 1, '0', 'ACTIVE', 'Y'),
  ('CLOSER_SALES_OVERFLOW', 'agent002', 2, '0', 'ACTIVE', 'Y');
Enter fullscreen mode Exit fullscreen mode

Field explanations:

  • agent_priority: 1=highest priority, 9=lowest. Lower number gets called first
  • closer_flag: 'Y' = this agent handles closer calls (must be 'Y')
  • agent_status: 'ACTIVE'='available', 'INACTIVE'='unavailable', 'DELETED'='removed'
  • lead_id: Usually '0' for in-group assignments; can specify a particular lead

Step 3.2: Configure Individual Agent Closer Permissions

Each agent needs ViciDial user account flags enabled. Update the vicidial_users table:

UPDATE vicidial_users 
SET 
  closer_enabled = '1',
  closer_campaigns = 'CLOSER_SALES',
  call_transfer_flag = '1',
  no_outbound_calls = '0',
  can_transfer_to_other_users = '1'
WHERE user_id IN ('agent001', 'agent002', 'agent003', 'agent004');
Enter fullscreen mode Exit fullscreen mode

Critical fields:

  • closer_enabled: Set to '1' to allow agent to receive closer calls
  • closer_campaigns: Comma-separated list of campaigns agent can handle
  • call_transfer_flag: Enables blind/attended transfers
  • can_transfer_to_other_users: Allows warm transfer to other agents

Verify settings:

mysql -u root -p asterisk -e "SELECT user_id, closer_enabled, closer_campaigns FROM vicidial_users WHERE user_id IN ('agent001','agent002','agent003','agent004');"
Enter fullscreen mode Exit fullscreen mode

Step 3.3: Set Agent Pause Codes for In-Group Work

Create pause codes specific to closer work:

INSERT INTO vicidial_pause_codes (
  pause_code,
  pause_name,
  inbound_seconds,
  outbound_seconds,
  active
) VALUES
  ('CLOSER', 'Closer Call In Progress', 0, 0, 'Y'),
  ('CLOSER_BREAK', 'Closer Break', 300, 300, 'Y'),
  ('CLOSER_LUNCH', 'Closer Lunch', 3600, 3600, 'Y');
Enter fullscreen mode Exit fullscreen mode

These codes appear in agent's pause dropdown in /agc/vicidial.php interface.

Part 4: Configure Asterisk Dialplan Integration

Step 4.1: Verify Auto-Generated Extensions

ViciDial automatically creates extensions when you add a closer campaign. Verify in /etc/asterisk/extensions-vicidial.conf:

grep -A 30 "exten => 8900,1" /etc/asterisk/extensions-vicidial.conf | head -40
Enter fullscreen mode Exit fullscreen mode

You should see auto-generated closer campaign context. If missing, manually trigger regeneration:

/usr/share/astguiclient/astguiclient_closer_extension_sync.pl
Enter fullscreen mode Exit fullscreen mode

Step 4.2: Create Custom Transfer Extension (Optional)

To allow dialer agents to transfer calls to closer campaign, add to /etc/asterisk/extensions-vicidial.conf:

[ViciDial-Closer-Transfer]
exten => 1,1,NoOp(Closer Transfer Request to ${closer_queue})
 same => n,ViciDialCloserQueue(${closer_queue}|${closer_priority}|${CALLERID(num)})
 same => n,Hangup()

exten => i,1,NoOp(Invalid extension)
 same => n,Playback(invalid)
 same => n,Hangup()

exten => t,1,NoOp(Transfer timeout)
 same => n,Hangup()
Enter fullscreen mode Exit fullscreen mode

Step 4.3: Reload Asterisk Configuration

asterisk -rx "dialplan reload"
Enter fullscreen mode Exit fullscreen mode

Verify dialplan loaded:

asterisk -rx "dialplan show ViciDial-Closer-Transfer"
Enter fullscreen mode Exit fullscreen mode

Expected output:

[ ViciDial-Closer-Transfer ]
'1' =>            1. NoOp(Closer Transfer Request to ${closer_queue})
                  2. ViciDialCloserQueue(${closer_queue}|${closer_priority}|${CALLERID(num)})
                  3. Hangup()
Enter fullscreen mode Exit fullscreen mode

Part 5: Test the Closer Campaign

Step 5.1: Pre-Test Verification Checklist

Before testing, verify all components in database:

#!/bin/bash
# Test script for closer campaign setup

CAMPAIGN="CLOSER_SALES"
DB="asterisk"

echo "=== Campaign Configuration ==="
mysql -u root -p "$DB" -e "SELECT campaign_id, campaign_type, active FROM vicidial_campaigns WHERE campaign_id='$CAMPAIGN';"

echo -e "\n=== In-Groups ==="
mysql -u root -p "$DB" -e "SELECT ingroup_id, ingroup_name, active FROM vicidial_ingroups WHERE campaign_id='$CAMPAIGN';"

echo -e "\n=== Agent Assignments ==="
mysql -u root -p "$DB" -e "SELECT ingroup_id, user_id, agent_priority, closer_flag FROM vicidial_ingroup_agents WHERE ingroup_id LIKE '$CAMPAIGN%';"

echo -e "\n=== Agent Closer Status ==="
mysql -u root -p "$DB" -e "SELECT user_id, closer_enabled, closer_campaigns FROM vicidial_users WHERE closer_enabled='1' LIMIT 5;"
Enter fullscreen mode Exit fullscreen mode

Run this script:

chmod +x test_closer_config.sh
./test_closer_config.sh
Enter fullscreen mode Exit fullscreen mode

Step 5.2: Manual Agent Availability Test

Log in agents to the system and verify they appear available for closer calls:

# Check current agent statuses
mysql -u root -p asterisk -e "SELECT user_id, status, campaign_id, on_call FROM vicidial_users WHERE user_id IN ('agent001','agent002','agent003');"
Enter fullscreen mode Exit fullscreen mode

Step 5.3: Simulate Incoming Call to In-Group

Use Asterisk CLI to originate test call:

asterisk -rx "channel originate SIP/2000 extension 8900@CLOSER_SALES_MAIN-inbound"
Enter fullscreen mode Exit fullscreen mode

Monitor Asterisk logs in real-time:

tail -f /var/log/asterisk/messages | grep -i "closer\|ingroup\|queue"
Enter fullscreen mode Exit fullscreen mode

Step 5.4: Monitor Call Routing

Check Asterisk queue status:

asterisk -rx "queue show CLOSER_SALES_MAIN"
Enter fullscreen mode Exit fullscreen mode

Expected output:

CLOSER_SALES_MAIN has 0 calls (max unlimited) in 'rrordered' strategy
     agent001 (SIP/2000) (paused) (Not in call, paused 0m 45s)
     agent002 (SIP/2001) (ready) (Penalty: 2)
     agent003 (SIP/2002) (ready) (Penalty: 3)
Enter fullscreen mode Exit fullscreen mode

Step 5.5: Verify Call Logging

After test call completes, verify logs:

mysql -u root -p asterisk -e "
SELECT 
  call_id,
  caller_id,
  customer_id,
  campaign_id,
  start_time,
  call_duration,
  status
FROM vicidial_closer_log 
WHERE campaign_id='CLOSER_SALES' 
ORDER BY start_time DESC 
LIMIT 5;
"
Enter fullscreen mode Exit fullscreen mode

Part 6: Advanced Configuration

Step 6.1: Implement Call Distribution Strategy

Closer in-groups support multiple distribution strategies. Configure in vicidial_ingroups:

UPDATE vicidial_ingroups 
SET 
  call_distribution_method = 'rrordered',
  max_concurrent_calls = '5',
  force_return_to_hold = 'N'
WHERE ingroup_id = 'CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode

Distribution methods:

  • rrordered: Round-robin by agent priority (default, recommended)
  • leastrecent: Agent with oldest last call
  • fewestcalls: Agent with fewest total calls today
  • random: Random agent selection

Step 6.2: Configure Callback Rules

Allow agents in closer campaign to schedule callbacks:

UPDATE vicidial_campaigns 
SET 
  closer_dial_campaign = 'CLOSER_SALES_CB',
  callback_dial_method = 'MANUAL',
  callback_hours_start = '08:00:00',
  callback_hours_end = '20:00:00'
WHERE campaign_id = 'CLOSER_SALES';
Enter fullscreen mode Exit fullscreen mode

This requires a separate dialer campaign (CLOSER_SALES_CB) created for callback origination.

Step 6.3: Implement DNC (Do Not Call) Filtering

Link in-group to DNC lists:

INSERT INTO vicidial_ingroup_dnc_filters (
  ingroup_id,
  dnc_filter_id,
  active
) VALUES
  ('CLOSER_SALES_MAIN', 'FEDERAL_DNC', 'Y'),
  ('CLOSER_SALES_MAIN', 'COMPANY_DNC', 'Y'),
  ('CLOSER_SALES_MAIN', 'INTERNAL_DNC', 'Y');
Enter fullscreen mode Exit fullscreen mode

Step 6.4: Set Up Custom CID Masking

Force specific outbound CID for transfers from this in-group:

UPDATE vicidial_ingroups 
SET 
  outbound_cid = '18005551234',
  outbound_cid_name = 'Sales Department',
  cid_mask_method = 'FORCED'
WHERE ingroup_id = 'CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode

Step 6.5: Configure Call Recording Exceptions

Set custom recording preferences:

UPDATE vicidial_ingroups 
SET 
  recording_call_display_name = 'CLOSER_SALES_MAIN_REC',
  call_recording_compression = '32',
  call_recording_quality = 'gsm',
  recording_enabled = 'Y'
WHERE ingroup_id = 'CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode

Part 7: Performance Tuning

Step 7.1: Optimize Queue Timeout Settings

Based on team size and call volume, adjust timeouts:

UPDATE vicidial_ingroups 
SET 
  call_timeout = '120',           -- 2 min normal calls
  callback_timeout = '180'        -- 3 min callbacks
WHERE ingroup_id = 'CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode

Monitor actual wait times:

mysql -u root -p asterisk -e "
SELECT 
  DATE(start_time) as Date,
  COUNT(*) as Total_Calls,
  AVG(wait_time) as Avg_Wait_Sec,
  MAX(wait_time) as Max_Wait_Sec
FROM vicidial_closer_log
WHERE campaign_id='CLOSER_SALES'
  AND start_time > DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY DATE(start_time)
ORDER BY Date DESC;
"
Enter fullscreen mode Exit fullscreen mode

Step 7.2: Monitor Agent Adherence to In-Group

Track agent time allocation across in-groups:

SELECT 
  user_id,
  ingroup_id,
  COUNT(*) as calls_handled,
  AVG(call_duration) as avg_duration,
  SUM(call_duration) as total_talk_time
FROM vicidial_closer_log
WHERE DATE(start_time) = CURDATE()
GROUP BY user_id, ingroup_id
ORDER BY total_talk_time DESC;
Enter fullscreen mode Exit fullscreen mode

Step 7.3: Set Agent Concurrent Call Limits

Prevent single agent from receiving multiple simultaneous calls:

UPDATE vicidial_users 
SET 
  max_concurrent_calls = '1',
  force_logout_after_seconds = '0'
WHERE user_id IN ('agent001', 'agent002', 'agent003', 'agent004');
Enter fullscreen mode Exit fullscreen mode

Part 8: Troubleshooting

Issue: Calls Not Routing to In-Group

Symptom: Incoming calls to DID don't reach agent queues, instead hangup or disconnect.

Root causes & solutions:

  1. Campaign not active:
mysql -u root -p asterisk -e "SELECT campaign_id, active FROM vicidial_campaigns WHERE campaign_id='CLOSER_SALES';"
Enter fullscreen mode Exit fullscreen mode

If active is 'N', update:

UPDATE vicidial_campaigns SET active='Y' WHERE campaign_id='CLOSER_SALES';
Enter fullscreen mode Exit fullscreen mode
  1. In-group not linked to campaign:
mysql -u root -p asterisk -e "SELECT ingroup_id, campaign_id FROM vicidial_ingroups WHERE campaign_id='CLOSER_SALES';"
Enter fullscreen mode Exit fullscreen mode
  1. Dialplan context missing:
asterisk -rx "dialplan show CLOSER_SALES | head -20"
Enter fullscreen mode Exit fullscreen mode

If no output, regenerate:

/usr/share/astguiclient/astguiclient_extension_update.pl
asterisk -rx "dialplan reload"
sleep 2
asterisk -rx "module reload pbx_config"
Enter fullscreen mode Exit fullscreen mode
  1. SIP routing issue - verify SIP profile includes ViciDial context:
grep -A 5 "context=" /etc/asterisk/sip-vicidial.conf | head -20
Enter fullscreen mode Exit fullscreen mode

Issue: Agents Not Receiving Calls Despite Being Available

Symptom: Agents log in, show as READY, but calls don't route to them.

Diagnosis:

# Check agent in-group membership
mysql -u root -p asterisk -e "
SELECT u.user_id, u.status, ia.ingroup_id, ia.closer_flag 
FROM vicidial_users u 
LEFT JOIN vicidial_ingroup_agents ia ON u.user_id = ia.user_id 
WHERE u.user_id='agent001';
"
Enter fullscreen mode Exit fullscreen mode

Solutions:

  1. If ingroup_id is NULL, agent not assigned to in-group. Re-run Step 3.1.

  2. Verify closer_enabled flag:

mysql -u root -p asterisk -e "SELECT user_id, closer_enabled FROM vicidial_users WHERE user_id='agent001';"
Enter fullscreen mode Exit fullscreen mode
  1. Check if agent paused:
asterisk -rx "show channels | grep agent001"
Enter fullscreen mode Exit fullscreen mode

If showing paused status, use admin panel to unpause or force status:

UPDATE vicidial_users SET status='READY' WHERE user_id='agent001';
Enter fullscreen mode Exit fullscreen mode
  1. Check Asterisk queue membership:
asterisk -rx "queue show CLOSER_SALES_MAIN | grep agent001"
Enter fullscreen mode Exit fullscreen mode

Issue: High Call Abandonment Rate

Symptom: Calls dropping before reaching agents (>15% abandonment).

Analysis:

mysql -u root -p asterisk -e "
SELECT 
  ingroup_id,
  COUNT(*) as total,
  SUM(CASE WHEN call_status='ABANDON' THEN 1 ELSE 0 END) as abandoned,
  ROUND(100*SUM(CASE WHEN call_status='ABANDON' THEN 1 ELSE 0 END)/COUNT(*), 2) as abandon_pct,
  AVG(wait_time) as avg_wait_sec
FROM vicidial_closer_log
WHERE DATE(start_time) = CURDATE()
  AND campaign_id='CLOSER_SALES'
GROUP BY ingroup_id;
"
Enter fullscreen mode Exit fullscreen mode

Solutions:

  1. Increase agents assigned: Add more agents to in-group or create overflow in-group.

  2. Reduce timeout: Lower call_timeout value (but not below 60 seconds):

UPDATE vicidial_ingroups SET call_timeout='90' WHERE ingroup_id='CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode
  1. Add voicemail option: Ensure voicemail_ext is configured:
UPDATE vicidial_ingroups SET voicemail_ext='9999' WHERE ingroup_id='CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode
  1. Implement callbacks: Enable callback option when queue full.

Issue: Calls Queuing But Not Distributed

Symptom: Queue shows calls waiting but agents not getting delivered calls.

Debug:

# Monitor queue in real-time
watch -n 1 'asterisk -rx "queue show CLOSER_SALES_MAIN"'
Enter fullscreen mode Exit fullscreen mode

Check agent member penalties:

mysql -u root -p asterisk -e "SELECT ingroup_id, user_id, agent_priority FROM vicidial_ingroup_agents WHERE ingroup_id='CLOSER_SALES_MAIN';"
Enter fullscreen mode Exit fullscreen mode

Solution: Agent priority (penalty in queue) must be ascending (1, 2, 3, etc.). If reversed, queue won't distribute:

UPDATE vicidial_ingroup_agents 
SET agent_priority = 1 
WHERE ingroup_id='CLOSER_SALES_MAIN' AND user_id='agent001';

UPDATE vicidial_ingroup_agents 
SET agent_priority = 2 
WHERE ingroup_id='CLOSER_SALES_MAIN' AND user_id='agent002';
Enter fullscreen mode Exit fullscreen mode

Reload queue:

asterisk -rx "queue reload"
Enter fullscreen mode Exit fullscreen mode

Issue: Calls Recording Not Working

Symptom: Closer calls complete but no recordings saved.

Check recording path:

ls -lah /var/spool/asterisk/monitor/ | tail -20
Enter fullscreen mode Exit fullscreen mode

Verify recording_enabled flag:

mysql -u root -p asterisk -e "SELECT ingroup_id, recording_enabled, recording_call_display_name FROM vicidial_ingroups WHERE ingroup_id='CLOSER_SALES_MAIN';"
Enter fullscreen mode Exit fullscreen mode

Enable recordings:

UPDATE vicidial_ingroups 
SET recording_enabled='Y' 
WHERE ingroup_id='CLOSER_SALES_MAIN';
Enter fullscreen mode Exit fullscreen mode

Check Asterisk logging:

grep -i "monitor\|record" /var/log/asterisk/messages | tail -30
Enter fullscreen mode Exit fullscreen mode

Disk space issue - common cause:

df -h /var/spool/asterisk/
Enter fullscreen mode Exit fullscreen mode

If full, archive old recordings:

find /var/spool/asterisk/monitor/ -mtime +30 -exec gzip {} \;
Enter fullscreen mode Exit fullscreen mode

Issue: Agent Can't Transfer Calls

Symptom: Closer agent attempts blind/attended transfer but fails.

Verify transfer permissions:

mysql -u root -p asterisk -e "SELECT user_id, call_transfer_flag, can_transfer_to_other_users FROM vicidial_users WHERE user_id='agent001';"
Enter fullscreen mode Exit fullscreen mode

Enable transfers:

UPDATE vicidial_users 
SET 
  call_transfer_flag='1',
  can_transfer_to_other_users='1'
WHERE user_id='agent001';
Enter fullscreen mode Exit fullscreen mode

Check Asterisk DTMF configuration - verify feature codes in /etc/asterisk/features.conf:

[featuremap]
blindxfer => #1          ; Blind transfer
atxfer => *2             ; Attended transfer
Enter fullscreen mode Exit fullscreen mode

Test with CLI:

asterisk -rx "core show hints | grep agent001"
Enter fullscreen mode Exit fullscreen mode

Part 9: Monitoring & Reporting

Dashboard Query: Real-Time In-Group Status

SELECT 
  ig.ingroup_id,
  ig.ingroup_name,
  COUNT(DISTINCT CASE WHEN u.status='READY' THEN u.user_id END) as available_agents,
  COUNT(DISTINCT CASE WHEN u.status='IN_CALL' THEN u.user_id END) as busy_agents,
  COUNT(DISTINCT CASE WHEN u.status='PAUSED' THEN u.user_id END) as paused_agents,
  (SELECT COUNT(*) FROM vicidial_log vl 
   WHERE vl.ingroup_id = ig.ingroup_id 
   AND vl.call_status = 'WAITING') as calls_waiting
FROM vicidial_ingroups ig
LEFT JOIN vicidial_ingroup_agents iag ON ig.ingroup_id = iag.ingroup_id
LEFT JOIN vicidial_users u ON iag.user_id = u.user_id
WHERE ig.campaign_id='CLOSER_SALES'
GROUP BY ig.ingroup_id, ig.ingroup_name;
Enter fullscreen mode Exit fullscreen mode

Daily Performance Report

SELECT 
  DATE(start_time) as call_date,
  ingroup_id,
  COUNT(*) as total_calls,
  SUM(CASE WHEN call_status='COMPLETED' THEN 1 ELSE 0 END) as completed_calls,
  SUM(CASE WHEN call_status='ABANDON' THEN 1 ELSE 0 END) as abandoned_calls,
  ROUND(AVG(wait_time), 1) as avg_wait_seconds,
  ROUND(AVG(call_duration), 1) as avg_talk_seconds,
  ROUND(SUM(call_duration)/COUNT(*), 1) as avg_handle_time_seconds
FROM vicidial_closer_log
WHERE campaign_id='CLOSER_SALES'
  AND start_time BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND NOW()
GROUP BY DATE(start_time), ingroup_id
ORDER BY call_date DESC, ingroup_id;
Enter fullscreen mode Exit fullscreen mode

Agent Productivity Report

SELECT 
  u.user_id,
  u.full_name,
  COUNT(DISTINCT cl.call_id) as calls_handled,
  SUM(cl.call_duration) as total_talk_time,
  ROUND(AVG(cl.call_duration), 1) as avg_talk_time,
  SUM(cl.wait_time) as total_wait_time,
  COUNT(DISTINCT CASE WHEN cl.call_status='COMPLETED' THEN cl.call_id END) as completed_calls
FROM vicidial_users u
LEFT JOIN vicidial_closer_log cl ON u.user_id = cl.assigned_to 
  AND DATE(cl.start_time) = CURDATE()
WHERE u.closer_enabled='1'
GROUP BY u.user_id, u.full_name
ORDER BY calls_handled DESC;
Enter fullscreen mode Exit fullscreen mode

Summary

Configuring ViciDial closer campaigns and in-groups involves seven critical steps:

  1. Create the closer campaign in web UI with appropriate dialing and recording settings
  2. Define in-groups as call queues within the campaign, setting timeouts and priorities
  3. Assign agents to in-groups with individual priorities and closer permissions
  4. Enable Asterisk integration by verifying dialplan contexts and reloading configuration
  5. Test thoroughly using Asterisk CLI and database verification queries
  6. Optimize performance through distribution strategy tuning and timeout adjustments
  7. Monitor continuously with real-time queries and daily reports

Key production-grade practices:

  • Always verify database changes with SELECT queries before and after modifications
  • Use agent priorities (1-3 range) for fair call distribution
  • Enable call recording on all in-groups for compliance and quality assurance
  • Set reasonable timeouts (120-180 seconds) to prevent excessive call abandonment
  • Create overflow in-groups to handle peak traffic periods
  • Test complete call flow end-to-

Top comments (0)