We have an Asterisk IVR system setup that prompts the user for input
In our extensions file, we have the following:
[englishprocess]
exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,Set(TIMEOUT(digit)=2)
exten => s,n,agi(mstts.agi,"Please enter your ID number followed by pound.",en-US)
exten => s,n,Read(APCODE,,666)
exten => s,n,agi(mstts.agi,"Your ID Number is",en)
exten => s,n,SayDigits(${APCODE})
exten => s,n,agi(mstts.agi,"If this is correct press, 1, otherwise, press, 3",en-US)
exten => s,n,Read(CHECK,,1)
exten => s,n,GotoIf($["${CHECK}" = "3"]?englishprocess,s,1)
exten => s,n,Set(MYADDR=${CURL(webserviceaddress.php?idnum=${APCODE})})
exten => s,n,agi(mstts.agi,${MYADDR},en-US)
exten => s,n,Hangup()
The problem is that if the user inputs their ID before the text to speech prompt finishes, or if they hit 1 before it finishes saying
"If this is correct press, 1, otherwise, press, 3"
The service hangs up.
How can we keep the process the same and accept early user input?
If accepting user input early is not possible is there a way to prevent hangup and prompt again?
We switched to Amazon's Polly service to generate the sound files and used the asterisk method Playback(filename) instead of agi() inside of extensions_custom.conf in order to stop the call from hanging up if the user inputs text prematurely.
Granted the service ignores the inputs that are put in early, but at least it does not hang up. A better solution would accept early input. I'll update this if I find an alternative.
Edit: Found an alternative Read() which lets us play soundbites that can be interrupted, so we now have a mix of Read() and playback() calls and can control which sound files can be skipped by the user in this way. The service no longer hangs up on users and we no longer use agi() calls.
Asterisk Dialplan cannot by use seriously to create dynamic services with intensive TextToSpeech.
First because the latency could be an issue if you don't use a cache, or if you don't use an MRCP connector.
Secondly because by this way you not support the bargein (https://www.w3.org/TR/voicexml20/#dml4.1.5) and you lost the way to interact with DTMF (or voice) at any moment.
To create a Voice Portal, you probably need a VoiceXML interpreter. You have 2 ways to create this service in an Asterisk : Voximal a commercial application running over and Asterisk, or VoiceGlue a free GPL dead project (you can run it over old Asterisk).
agi(mstts.agi,"text",[language],[intkey],[speed]):
intkey is used if the user enters anything the script will stop and go to that extension. I don't know if it will work in your case but worth a try.
exten => _X,1,agi(mstts.agi,"You just pressed ${EXTEN}. Try another one please.",en,any)
Try using the ,any after the language and see if that works. I got that example from https://github.com/zaf/asterisk-mstts
Look into this line:
print "STREAM FILE $file \"$keys\"\n";
https://www.voip-info.org/wiki/view/stream+file
Usage: STREAM FILE <filename> <escape digits> [sample offset]
Send the given file, allowing playback to be interrupted by the given digits, if any.
Use double quotes for the digits if you wish none to be permitted.
If sample offset is provided then the audio will seek to sample offset before play starts.
Remember, the file extension must not be included in the filename.
After that it for some reason work like waitexten and change extension. I have no idea who and why added that to code, you can ask maintainer.
So just read files you use, not spam questions.
Related
I'm implementing a callback service for Asterisk queues.
The idea is to place all incoming calls on a queue. A message is played back, letting callers know that they can either wait in line until an agent becomes available or they can press '2', hangup, and have the agent call them back as soon as possible.
I defined a context for the inbound queue in queues.conf as such:
[qIngresoCC]
...
context=qIngresoCC-callback
...
and defined the corresponding entries in extensions.conf:
[qIngresoCC-callback]
exten = > 2,1,NoOp("El cliente ${CALLERID(all)} solicita CallBack")
same => n,AGI(add_channel_to_callback.php)
same => n,Playback(goodbye_for_the_best)
same => n,Hangup()
An incoming call is correctly sent to the queue, the announcements are played back, but when pressing '2', the call is not sent to the qIngresoCC-callback context.
DTMF logging is enabled, and I can see Asterisk receiving it, but it simply won't jump to the specified context.
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4017 __ast_read: DTMF end '2' received on SIP/axtel-rappi-0000027b, duration 0 ms
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4076 __ast_read: DTMF end accepted without begin '2' on SIP/axtel-rappi-0000027b
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4087 __ast_read: DTMF end passthrough '2' on SIP/axtel-rappi-0000027b
What am I missing?
UPDATE
I forgot to specify:
I'm using Asterisk 13.14.0 compiled from source (by Portage) on Gentoo, with support (USE flags) for caps, curl, http, iconv, odbc, pjproject, postgres, samples, srtp.
I'm not using freepbx nor any other GUI. Everything is configured manually through the .conf files.
The only tuning of the source I did was changing channel.h from #define AST_MAX_ACCOUNT_CODE 20 to #define AST_MAX_ACCOUNT_CODE 256 to be able to use longer account codes.
The digit pressed must match the extension level in the context: for example if you have context=queue_out in your queues.conf and let's say your recording says "Press 5 to leave a voicemail (periodic announcement): extensions.conf would have the following
[queue_out]
exten => 5,1,Voicemail(123#default)
exten => 5,n,Hangup()
I had the same problem btw.
I want to call an ext in a phone number .
For example +982632601 ext 8 .
In most phones we could directly call +982632601#8 without need to listen to IVR .
I tried following characters
# * w , p
Any ideas ?
You need have support from dialplan and hardware side on asterisk server to do that.
Zoiper can do nothing with that.
What you do is calling "two stage dialling"
In asterisk it can be done via D param of dialling command something like this:
exten => *20,1,Dial(Local/18005558355#outbound-allroutes,,D(wwww932))
Sure you need parse by dialplan your number and change your dialplan to support that. You can use any character.
Sorry, dialplan for 2-stage-dialling is not trivial and out of this site topics.
Below are some asterisk dial plan examples that I have copied from somewhere.
exten => s,1,Answer()
exten => s,n,Playback(hello-world)
exten => s,n,Hangup()
The first line indicates when a new call comes into the channel it goes to extension s (top priority) 1 which is tied to the application Answer().
After that it goes to PlayBack(hello-world) and then the call is hung up.
Now the next section
[incoming]
exten => 123,1,Answer()
exten => 123,n,Background(main-menu)
exten => 1,1,Playback(digits/1)
exten => 1,n,Goto(incoming,123,1)
exten => 2,1,Playback(digits/2)
exten => 2,n,Goto(incoming,123,1)
Call is coming to extension 123.(Is this a new menu??) or is it forwarded from extension 's'.I think I am missing the connecting link here.
The second line says
exten => 123,n,Background(main-menu).
What is main-menu here? Where is it defined?
Background is simililar to Playback application in that it plays file (main-menu is audio file that most likely would be found in /var/lib/asterisk/sounds/ directory).
While Playback plays the whole file before returning control. Background starts playing the file and returns control immediately so you can execute other commands.
For more information refer to:
voip-info.org - Playback and Background
wiki.asterisk.org - Playback and Background
[incoming]
exten => 123,1,Answer()
When asterisk receives incoming call on a channel, asterisk look at the context defined for that channel (incoming is the name of that context - usually the default context for incoming calls). The context has different commands depending on what extension the you have dialed.
If you have dialed 123 it will start playing some kind of automatic menu.
If you have dialed 1 or 2 it will play the digit and redirect again to 123 and start playing the interactive menu
Call is coming to extension 123.(Is this a new menu??) or is it forwarded from extension 's'.
This is the Extension, comes from the default context (maybe default includes incoming or by channel definition).
You could debug with a catchall exten, with
exten => _X.,1,NoOp(${CALLERID(NUM)} - ${EXTEN})
or
exten => 123,2,NoOp(${CALLERID(NUM)} - ${EXTEN})
and you see the Noop's when you're connected to the asterisk CLI.
$ asterisk -rvvv
What is main-menu here? Where is it defined?
main-menu is a Audio File like "main-menu.gsm" (the directory is defined in asterisk.conf).
Asterisk decides which format/codec to use.
One other thing is that the "next section"
[incoming]
... is a dialplan "context". Contexts are a way of partitioning your dialplan; it's a box that holds its own set of variable, extensions, etc.. So in your example, the first context does not explicitly "Goto" or "Gosub" the call to the "Incoming" context, so the call in the first context cannot go there.
As for how the call would get into the "incoming" context, quite often that is defined with the phone trunk coming into the system. So in your appropriate SIP, IAX2 or PSTN trunks, you would have a line like:
context=incoming
... and that would force the call to go there. If the call was "addressed" to extension 123 via a "DID" or "Direct Inwards Dial" number, then it would hit that extension and the caller would be hearing a menu greeting.
I'm implementing an asterisk server.
I'm using PJSUA to send a wav file to my phone, passing through the asterisk server.
Here is my extension.conf
[appel-sortant] ; Initialisation
exten => _X.,1,Set(LOOP=0)
exten => _X.,2,Set(MAX=3)
exten => _X.,n,Set(ASTREINTE=${EXTEN})
exten => _X.,n,Goto(astreinte,${EXTEN},10)
exten => _X.,500,Hangup
[astreinte]
exten => _X.,10,Dial(SIP/${ASTREINTE}#forfait-ovh,20,gS(10))
exten => _X.,n,AMD()
exten => _X.,n,NoOp(${DIALSTATUS}) ; Here got ANSWER status
exten => _X.,n,NoOp(${AMDSTATUS}) ; Here got MACHINE or NOTSURE
exten => _X.,n,Hangup
My problem are :
1/ When i call my phone number while sending a wav file from PJSUA, the AMDSTATUS is MACHINE at the end of the call
2/ If I call with pjsua without wav file, I got a AMDSTATUS = NOTSURE.
Is AMD() detecting answering machines or caller machine ?
Here is my Pjsua line file :
pjsua --null-audio --local-port=5061 --id sip:username#192.168.X.X --registrar sip:192.168.X.X --realm * --username username --password password --auto-play --play-file=./sounds/sound.wav sip:0123456789#192.168.X.X
I'm currently on asterisk 1.6.2.9-2squeeze.
You'll need to play around with the settings in the AMD function. You have the following parameters:
AMD([initialSilence[,greeting[,afterGreetingSilence[,totalAnalysis Time[,miniumWordLength[,betweenWordSilence[,maximumNumberOfWords[,silenceThreshold[,maximumWordLength]]]]]]]]])
initialSilence - Is maximum initial silence duration before greeting.
If this is exceeded set as MACHINE
greeting - is the maximum length of a greeting.
If this is exceeded set as MACHINE
afterGreetingSilence - Is the silence after detecting a greeting.
If this is exceeded set as HUMAN
totalAnalysis Time - Is the maximum time allowed for the algorithm
to decide HUMAN or MACHINE
miniumWordLength - Is the minimum duration of Voice considered to be a word
betweenWordSilence - Is the minimum duration of silence after a word to consider the audio that follows to be a new word
maximumNumberOfWords - Is the maximum number of words in a greeting
If this is exceeded set as MACHINE
silenceThreshold - How long do we consider silence
maximumWordLength - Is the maximum duration of a word to accept.
If exceeded set as MACHINE
Based on the pattern of silence, sound, and length of sound detected from the pjsua application, you should be able to ascertain the correct values for those parameters to achieve the results you want.
Yes - AMD() detects if an answering machine picked up. The possible values it could return are:
MACHINE | HUMAN | NOTSURE | HANGUP
I don't know the inner-workings of the function, but if you're playing a wav file - amd() probably thinks it indeed is an answering machine.
It seems your scenario is providing the correct results. Your dial-plan and Pjsua line seem fine to me.
Hi
I am new to asterisk. I want to build an IVR system so that approximately 10-15 users can call simultaneously and use the same dialplan..
We have PRI lines and are thinking of buying Digium TE!21 card for my software.Would it serve my needs?
Please let me know how to configure dialpan and other configuration plans for my problem.
And can I simulate it without using a hartware before buying it?
Yes Asterisk makes a wonderful IVR platform. Especially because the IVR can be programmed in any language that can write to stdin and read from stdout.
You'll need read up on Asterisk on sites like this but in the interest of getting you going here is a teaser of a very simple menu.
[incoming-lines]
exten => s,1,Noop()
exten => s,n(msg),Background(Press1OrPress2)
exten => s,n,WaitExten(8)
exten => s,n,Hangup()
exten => 1,1,Playback(YouPressed1)
exten => 1,n,Goto(msg)
exten => 2,1,Playback(YouPressed2)
exten => 2,n,Goto(msg)
exten => t,1,Playback(YouTimedOut)
exten => t,n,Goto(msg)
exten => i,1,Placback(YouMadeInvalidEntry)
exten => i,n,Goto(msg)
Now that is obviously very silly but gets the point across. If you want to take it a step further there are packages like phpagi that allow you to program the IVR in PHP. The way to make the dialplan invoke the AGI script is.
[incoming-lines]
exten => s,1,Noop()
exten => s,n,agi("http://yourapache/yourscript.php")
exten => s,n,Hangup()
I'll leave it up to you to read up on phpagi but this should get you started. Yes you can simulate it without any hardware. You'll need a computer with Asterisk on it of course, and a soft phone, with a speaker. That's all it takes to test IVR.