Simple IVR with Timeout and Invalid Handling
Simple IVR with Timeout and Invalid Handling
A multi-attempt auto-attendant that replays the menu on bad input and hangs up gracefully after three failed attempts.
Dialplan
[ivr-main]
exten => s,1,Answer()
same => n,Set(ATTEMPTS=0)
same => n(menu),Set(ATTEMPTS=$[${ATTEMPTS} + 1])
same => n,GotoIf($[${ATTEMPTS} > 3]?maxretry,1)
same => n,Background(custom/welcome)
same => n,WaitExten(5)
; Option routing
exten => 1,1,Goto(sales,s,1)
exten => 2,1,Goto(support,s,1)
exten => 0,1,Goto(operator,s,1)
; Invalid keypress -- replay menu, up to 3 times
exten => i,1,Playback(pbx-invalid)
same => n,Goto(s,menu)
; Timeout waiting for input -- replay menu up to 3 times total, then give up
exten => t,1,GotoIf($[${ATTEMPTS} < 3]?s,menu)
same => n,Goto(maxretry,1)
; Max retries reached
exten => maxretry,1,Playback(vm-goodbye)
same => n,Hangup()
How it works
- Attempt counter:
ATTEMPTSincrements on every pass throughmenu. After 3 tries (invalid or timeout), the call goes tomaxretryand hangs up. i(invalid): Fires when the caller presses a digit that matches no extension in the current context.Playback(pbx-invalid)tells them the input was not recognized, then the call loops back to the menu label.t(timeout): Fires whenWaitExten()expires with no input. On the first two timeouts it replays the menu; on the third it hangs up.Background()vsPlayback():Background()listens for DTMF while the audio plays. A keypress interrupts the prompt immediately.Playback()ignores keypresses entirely; use it for error messages and farewells.
Tips
- Replace
custom/welcomewith a real recorded prompt. Record it at 8kHz mono and save as.gsmor.ulawin/var/lib/asterisk/sounds/custom/. - Keep
WaitExten()to 5 seconds or less. Longer timeouts frustrate callers who are already listening to dead air. - For multi-level IVRs, each menu level gets its own context. Use
Goto()to move between them and resetATTEMPTSwhen entering a new level. - Add
exten => #,1,Goto(s,menu)if you want callers to be able to replay the menu by pressing#.
User Notes
Know a tip or gotcha for this topic? Share it below and help others.
Contribute a note
Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.