Welcome to the world of Asterisk dialplan programming. There's a couple issues that I can spot right away, so let me start with a little intro...
- ALL contexts need to have an "exten" declaration to process
- Each context can and will likely have many extension entries. Each extension needs to start with an "exten" declaration.
- The "same" entry means "use the 'exten => xxx,' from above"
- The "n" priority means, next number; increment the above priority by 1 then use it.
So, let's use an example of:
[context]
exten => 111,1,Noop(Start here)
exten => 111,2,Answer()
exten => 111,2,Goto(another_context,exten,priority)
To simplify, we can use "same" and "n":
[context]
exten => 111,1,Noop(Start here)
same => n,Answer()
same => n,Goto(another_context,exten,priority)
The second example is exactly identical to the first, but allows you to insert a new entry into the dialplan and it's renumbered for you. You can also change the extension on the first line, without needing to edit each line.
To begin with your example, I see you start off [main-menu] with:
exten => n(menuprompt),Background(main-menu)
There is no extension to dial here. You can add one like this:
exten => 5432,n(menuprompt),Background(main-menu)
However, this is still an issue, since the "n" mean next priority in this context, and nothing was used above it... so n is undefined. You must start each extension within a context with a defined number, like 1:
exten => 5432,1(menuprompt),Background(main-menu)
Now, you likely don't need to have an "extension" assigned to this entry, so you can use this:
exten => s,1(menuprompt),Background(main-menu)
Now, what Asterisk will do after playing the above sound is look for the next priority in the 's' extension. So, in this case, "main-menu,s,2." Since there is no entry there, it's up to asterisk to choose its default behavior and this is considered to be a security risk. Add the following, for example:
same => n,WaitExten(10)
same => n,Goto(menuprompt)
This will wait 10 seconds for the caller to enter something recognizable in this context. Note that we only supplied "menuprompt" to Goto, and it'll default to looking in the current context only. This will loop indefinitely. Ideally, you'd want to count the number of failed entries and do something different after X times waiting and receiving nothing. Also, note that if the caller enters 5, for example, this is unrecognized and the caller will be sent to the "i" extension, for "invalid." So, add this:
exten => i,1,Playback(invalid-message)
same => n,Goto(menuprompt)
The same thing applies here... ideally you should check the # of attempts and do something different if they keep making invalid selections.
Lastly in this context, your 3 & 4 options will fail on Goto. Change to the simplified version just above.
Now, for your "incoming" context. This looks more correct. A call coming in to 123, will be answered and a sound file will be played. Selection 1 & 2 will trigger, but will fail after playback. You have to change your Goto calls to this:
Goto(incoming,123,menuprompt)
That's context, exten, priority. With the correction, If they select 1 or 2 while the file is playing, it'll play the appropriate sound file then go back to the prompt again. 9 will of course hang up on the caller.
Now, let's take your example and simplify it a little:
[incoming]
exten => 123,1,Answer()
same => n(menuprompt),Background(main-menu)
exten => 1,1,Playback(digits/1)
same => n,Goto(123,menuprompt)
Next on my list is that there's no way to get from "incoming" to "main-menu." As an example, we can add the following:
exten => 0,1,Goto(main-menu,s,1)
Now when a caller receives the first menu, they can press 0 to get to the second menu. I'd suggest changing your "Background" entries to something new to not be confusing. It should be the name of the sound file and while it CAN be what it is, there's no significance to it being "main-menu." Perhaps use "main-menu-sound-file."
This is your file with my corrections and added examples. It still needs to be built out more, but one step at a time, especially when you're leaning the syntax.
[incoming]
exten => 123,1,Answer()
same => n(menuprompt),Background(main-menu-sound-file)
same => n,WaitExten(10)
same => n,Goto(menuprompt)
exten => 1,1,Playback(digits/1)
same => n,Goto(menuprompt,
exten => 2,1,Playback(digits/2)
same => n,Goto(menuprompt)
exten => 9,1,Hangup()
exten => 0,1,Goto(main-menu,s,1)
exten => i,1,Playback(invalid-message)
same => n,Goto(menuprompt)
[main-menu]
exten => s,1(menuprompt),Background(main-menu-sound-file)
same => n,WaitExten(10)
same => n,Goto(menuprompt)
exten => 3,1,Playback(digits/3)
same => n,Goto(main-menu,menuprompt,n)
exten => 4,1,Playback(digits/4)
same => n,Goto(main-menu,menuprompt,n)
exten => 9,1,Hangup()
exten => i,1,Playback(invalid-message)
same => n,Goto(menuprompt)
I hope this helps! Happy coding!