; ============================================================================= ; VICIdial Inbound IVR — Complete Setup Configuration ; ============================================================================= ; Generated by ViciStack — https://vicistack.com — Free VICIdial optimization ; ; WHAT THIS FILE DOES: ; Complete IVR (Interactive Voice Response) configuration for inbound ; campaigns: business hours routing, multi-level menu, hold queue with ; position announcements, overflow to voicemail, skill-based routing, ; and after-hours handling. ; ; HOW TO USE: ; 1. IVR menu structure is configured in VICIdial Admin > Inbound > ; Call Menus. The Asterisk dialplan entries below handle the ; low-level call flow. ; 2. Copy the [vicidial-ivr] context to /etc/asterisk/extensions_custom.conf ; 3. Configure the In-Group and Call Menu in VICIdial admin ; 4. Reload: asterisk -rx "dialplan reload" ; ; FULL GUIDE: ; https://vicistack.com/blog/vicidial-ivr-setup/ ; https://vicistack.com/blog/vicidial-inbound-setup/ ; https://vicistack.com/blog/vicidial-inbound-queue-routing/ ; https://vicistack.com/blog/call-center-after-hours/ ; ; NEED HELP? hello@vicistack.com ; ============================================================================= ; ============================================================================= ; PART 1: ASTERISK DIALPLAN — Custom IVR Context ; ============================================================================= ; Add this to /etc/asterisk/extensions_custom.conf ; This handles the call flow BEFORE VICIdial's in-group routing takes over. ; ; Replace: ; MAIN_DID = your main inbound number (e.g., 18005551234) ; COMPANY_NAME = your company name for text-to-speech fallback ; SALES_INGROUP = your VICIdial sales in-group ID ; SUPPORT_INGROUP = your VICIdial support in-group ID ; ============================================================================= ; --- extensions_custom.conf --- [vicidial-ivr] ; === Main IVR Entry Point === ; Caller hits this when they dial your main number. ; Answer, wait 500ms for audio to stabilize, then route based on time. exten => MAIN_DID,1,Answer() exten => MAIN_DID,n,Wait(0.5) ; Wait is critical — without it, the first 200-400ms of audio is clipped ; on some carriers. SIP INVITE to 200 OK to RTP flow takes time. exten => MAIN_DID,n,Set(CHANNEL(language)=en) exten => MAIN_DID,n,GotoIfTime(08:00-17:00,mon-fri,*,*?business-hours,s,1) exten => MAIN_DID,n,GotoIfTime(08:00-13:00,sat,*,*?saturday-hours,s,1) exten => MAIN_DID,n,Goto(after-hours,s,1) ; === Business Hours Menu (Mon-Fri 8am-5pm) === [business-hours] exten => s,1,Set(TIMEOUT(digit)=5) ; digit timeout: seconds to wait for DTMF input. 5s is generous but ; prevents timeout on elderly callers who dial slowly. exten => s,n,Set(TIMEOUT(response)=10) ; response timeout: total seconds to wait before repeating the menu. exten => s,n,Set(loopcount=0) exten => s,n(menu),Background(custom/main-greeting) ; Record your greeting as: ; "Thank you for calling [Company]. For sales, press 1. For support, ; press 2. For billing, press 3. To repeat this menu, press 9." ; Save as /var/lib/asterisk/sounds/custom/main-greeting.wav ; Format: 8kHz mono PCM WAV (Asterisk native). Convert with: ; sox input.wav -r 8000 -c 1 -b 16 custom/main-greeting.wav exten => s,n,WaitExten(8) ; WaitExten after Background — this catches DTMF entered during or ; after the greeting plays. Without it, early key presses are lost. ; Menu option 1: Sales exten => 1,1,Playback(custom/transferring-sales) ; "Please hold while I connect you to our sales team." exten => 1,n,Goto(sales-queue,s,1) ; Menu option 2: Support exten => 2,1,Playback(custom/transferring-support) exten => 2,n,Goto(support-queue,s,1) ; Menu option 3: Billing exten => 3,1,Playback(custom/transferring-billing) exten => 3,n,Goto(billing-queue,s,1) ; Menu option 9: Repeat menu exten => 9,1,Goto(business-hours,s,menu) ; Invalid input or timeout — replay up to 3 times, then route to operator exten => i,1,Playback(custom/invalid-option) exten => i,n,Set(loopcount=$[${loopcount}+1]) exten => i,n,GotoIf($[${loopcount}<3]?business-hours,s,menu) exten => i,n,Goto(operator-route,s,1) exten => t,1,Set(loopcount=$[${loopcount}+1]) exten => t,n,GotoIf($[${loopcount}<3]?business-hours,s,menu) exten => t,n,Goto(operator-route,s,1) ; === Saturday Hours (8am-1pm) === [saturday-hours] exten => s,1,Background(custom/saturday-greeting) ; "Thank you for calling on Saturday. Our hours are 8am to 1pm. ; For sales press 1, or hold for an agent." exten => s,n,WaitExten(8) exten => 1,1,Goto(sales-queue,s,1) exten => t,1,Goto(sales-queue,s,1) ; On Saturdays, timeouts go straight to sales (skeleton crew, no routing). ; === After Hours === [after-hours] exten => s,1,Playback(custom/after-hours-greeting) ; "Thank you for calling [Company]. Our offices are closed. ; Business hours are Monday through Friday, 8am to 5pm, ; and Saturday 8am to 1pm. Please leave a message after the tone ; and we'll return your call the next business day." exten => s,n,Voicemail(MAIN_DID@default,su) ; s = skip "is not available" prompt (we already played a greeting) ; u = mark as "unavailable" type exten => s,n,Hangup() ; === Operator / Fallback Route === [operator-route] exten => s,1,Playback(custom/connecting-operator) exten => s,n,Goto(sales-queue,s,1) ; Callers who can't navigate the menu go to sales. Sales handles everything. ; === Sales Queue === [sales-queue] exten => s,1,Set(CALLERID(name)=IVR-Sales-${CALLERID(num)}) ; Prepend source so agents know the call came through the IVR sales option. exten => s,n,AGI(agi://127.0.0.1:4577/--ATEA--SALES_INGROUP-----YES-default------1---) ; This AGI call hands the call to VICIdial's in-group routing engine. ; Replace SALES_INGROUP with your actual in-group ID. ; ; AGI parameter format (positional, pipe-delimited): ; --ATEA--[in_group]-----[fronter_display]-[call_menu]------[queue_priority]--- ; YES = play hold music while waiting for agent. ; === Support Queue === [support-queue] exten => s,1,Set(CALLERID(name)=IVR-Support-${CALLERID(num)}) exten => s,n,AGI(agi://127.0.0.1:4577/--ATEA--SUPPORT_INGROUP-----YES-default------1---) ; === Billing Queue === [billing-queue] exten => s,1,Set(CALLERID(name)=IVR-Billing-${CALLERID(num)}) exten => s,n,AGI(agi://127.0.0.1:4577/--ATEA--BILLING_INGROUP-----YES-default------1---) ; ============================================================================= ; PART 2: VICIDIAL IN-GROUP SETTINGS ; ============================================================================= ; Configure these in Admin > Inbound > In-Groups for each queue. ; These are the admin GUI settings, documented here for reference. ; ============================================================================= ; --- Queue Settings (per in-group) --- ; Queue Priority: 1-99. Lower number = higher priority. ; Use this when you have VIP callers or callbacks that should jump the line. ; Default: 50 (medium priority) queue_priority = 50 ; Hold Time Limit: Maximum seconds a caller waits before overflow action. ; 120-180 seconds is typical. Beyond 3 minutes, most callers hang up anyway. ; See: https://vicistack.com/blog/call-center-abandonment-rate/ hold_time_limit = 180 ; Hold Time Overflow Action: What happens when hold_time_limit is exceeded. ; Options: ; VOICEMAIL = send to voicemail box ; CALLMENU = send to another IVR menu (e.g., "all agents busy" message) ; IN_GROUP = overflow to another in-group (backup team) ; PHONE = ring a specific phone (manager's cell) ; DID = route to a different DID hold_overflow_action = VOICEMAIL hold_overflow_target = MAIN_DID@default ; Queue Position Announcements: Tell callers their position in line. ; Reduces hang-ups by ~15% (people will wait if they know they're next). ; Interval: seconds between announcements. queue_position_announce = Y queue_position_announce_interval = 45 ; "You are caller number 3. Your estimated wait time is 2 minutes." ; Requires custom audio files or festival TTS. ; Hold Music: Play music or promotional messages while waiting. ; Stock: default (Asterisk MOH). Replace with your branded hold audio. ; Copy your hold music to /var/lib/asterisk/mohmp3/ ; Configure in Asterisk: musiconhold.conf hold_music = default ; Agent Alert: How agents are notified of an inbound call. ; Options: RING, BEEP, NONE ; RING = phone rings (like a normal call). Best for blended campaigns. ; BEEP = quick beep in headset. Best for high-volume inbound-only. agent_alert = RING ; Estimated Wait Time: Show callers estimated wait in queue announcements. ; Based on average handle time and queue depth. ; Requires enough call history data to be accurate (~100 calls). estimated_wait_time = Y ; ============================================================================= ; PART 3: SKILL-BASED ROUTING ; ============================================================================= ; Route callers to agents with specific skills (e.g., Spanish speakers, ; product specialists, closers). ; ; Configure in VICIdial: ; 1. Admin > Users > [agent] > In-Group Rank: set skill level (1-9) ; 2. Admin > In-Groups > [in-group] > In-Group Rank: enable ranking ; 3. Routing: AGENT_RANK routes to highest-ranked available agent ; ; Example: Spanish support ; - Create in-group: SUPPORT_SPANISH ; - Set bilingual agents to rank 9 (primary) in this in-group ; - Set English-only agents to rank 1 (overflow) ; - Add IVR option: "Para espanol, oprima 5" ; - Route option 5 to SUPPORT_SPANISH in-group ; ============================================================================= ; Skill-based routing settings (per in-group) in_group_rank_routing = Y ; Y = use agent ranks for routing decisions ; Highest-ranked agent gets the call first. If no high-rank agents available, ; falls through to lower ranks. in_group_rank_secondary = LONGEST_WAIT_AGENT ; Within the same rank, use longest-wait routing. ; Prevents the same agent from getting all calls just because they have ; the highest rank. ; ============================================================================= ; PART 4: CALLER ID / CNAM LOOKUP ; ============================================================================= ; Display the caller's name on the agent screen for inbound calls. ; Requires a CNAM lookup service (OpenCNAM, Telnyx CNAM, etc.) ; ; See: https://vicistack.com/blog/vicidial-cnam-lookup-inbound/ ; ; Cost: $0.002-0.005 per lookup. Worth it — agents convert 10-15% better ; when they can greet callers by name. ; ============================================================================= ; ============================================================================= ; PART 5: AUDIO FILES CHECKLIST ; ============================================================================= ; Record these audio files and save to /var/lib/asterisk/sounds/custom/ ; Format: 8kHz mono 16-bit PCM WAV ; Convert: sox input.wav -r 8000 -c 1 -b 16 output.wav ; ; Required files: ; main-greeting.wav — Main business hours IVR greeting ; saturday-greeting.wav — Saturday hours greeting ; after-hours-greeting.wav — After hours / closed message ; transferring-sales.wav — "Connecting you to sales" ; transferring-support.wav — "Connecting you to support" ; transferring-billing.wav — "Connecting you to billing" ; invalid-option.wav — "Sorry, that's not a valid option" ; connecting-operator.wav — "Please hold for an operator" ; queue-position.wav — "You are caller number..." ; queue-thankyou.wav — "Thank you for holding" ; ; TIP: Use a professional voice actor. AI voices (ElevenLabs, etc.) are ; good enough for internal use but callers notice and it hurts trust. ; A professional 10-file recording package costs $200-500 and lasts years. ; ; For IVR setup and configuration services: ; https://vicistack.com — hello@vicistack.com ; =============================================================================