Asterisk dialplan SayNumber cmd limits - asterisk

I'm having a hard time thinking about a solution for this problem,
I'm using asterisk to develop a phone ivr smart application which needs some time to read number to the caller, the way asterisk work is using the file say.conf for building the audio files to play for the number to input.
For example, if I write saynumber(123) it will go into say.conf file and find the matching regex and then build list of files to play (for the example it will play /digits/hundred then digits/and then digits/twenty then digits/three,
Now to the problem:
The command SayNumber is not listening to the user input while playing the files which means that the user cant interrupt the system by typing some number on his phone and it's not convenient for the user.
The command Read(var,filestoplayseperatedby&) is capable of listening to the user dtmf input while playing list of files.
What I'm trying to achieve is getting the list of the files based on the say.conf file to a variable, then after I got the file I will use the Read command and the it will say the number while listening to the user input. I also don't want to use tts engines since its a multilingual application that not all of them are tts available (Hebrew etc.) Also tts won't solve the main issue listening to the user input while playing.
Sorry for my English, since I'm not a native English speaker.
Here is a part from the asterisk say.conf file:
_[n]um:X000000000 => num:${SAY:0:1}, digits/billion
_[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
_[n]um:XX000000000 => num:${SAY:0:2}, digits/billion
_[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
_[n]um:XXX000000000 => num:${SAY:0:3}, digits/billion
_[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
Any help will be appreciated.

You have 2 options
1) change saydigits to read digits(c/c++ programming)
2) give correct string to READ app(using fastagi/agi or other method)

Related

Change music on hold during Dial()

I'm using the parameter m(mymusic) in my call to Dial() to let the caller hear some music instead of the boring ring tone. However I'd like to have a different music file after some time. The time when the music changes should easily be changeable (by editing a variable), so it is no option to just create a music-on-hold-file which has X seconds of music 1 and then Y seconds of music 2.
What I want is basically this, but without a second Dial() and without an actual second call to ${device}, because that creates two "missed call" entries for one missed call, and it interrupts the phone's ring tone.
Set(time_until_new_music=20);
Dial(${device},${time_until_new_music},gm(music1));
if ( "${DIALSTATUS}" == "NOANSWER" ) {
Dial(${device},,m(music2));
}
Is this possible somehow?
Hold class can have unlimited number of different sound file of any length
Number of musiconhold classes also unlimited. So you can create your own set for every need
However you can't control from dialplan class info. You can use external steaming app and forward to that app param you need. Require expert level in both asterisk and linux.
Something like this may work:
s,1,Set(time_until_new_music=20)
s,2,Dial(${device},${time_until_new_music},gm(music1))
s,3,GotoIf($[${DIALSTATUS}=NOANSWER]?s,4:s,5)
s,4,Dial(${device},,m(music2))
s,5,Hangup()

Asterisk catch a Incoming call and transfer it to a specific exten

I have been building a Window Form desktop application using C# that interfaces with Asterisk using Asterisk.NET.
My first problem is catch a Incoming call and transfer it to specific exten.
The first my idea is using OriginateAction, when a call come, I use Dial event and catch it and use OriginateAction to call to a specific exten.
RedirectAction originateAction = new RedirectAction();
originateAction.Channel = e.Channel;
originateAction.Context = "default";
originateAction.Exten = "203";
originateAction.Priority = 1;
ManagerResponse originateResponse = manager.SendAction(originateAction);
Console.WriteLine(originateResponse);
But it not work like my wish.
The second my idea is using RedirectAction:
RedirectAction originateAction = new RedirectAction();
originateAction.Channel = e.Channel;
originateAction.Context = "default";
originateAction.Exten = "203";
originateAction.Priority = 1;
ManagerResponse originateResponse = manager.SendAction(originateAction);
Console.WriteLine(originateResponse);
And it not work.
I have find on many websites but the documents is very little.
How can I solve this issue?
Thanks!
I would suggest using some kind of dynamic dialplan instead of "catching" calls reactively. Why not use an AGI script?
Essentially, your application tells a database or other central system what to do when calls matching certain criteria come in. Then Asterisk runs the script you setup when calls reach a certain context (such as all incoming calls), and then the script routes the call dynamically based on the inputs given by your application.
Since you seem to like .NET, here's a .NET AGI project to help you get started: AsterNET. It looks like the library you mentioned, Asterisk.NET, is also capable of Fast CGI (what AGI uses), but the last release was in 2009, whereas AsterNet is active as recently as 3 months ago.
I personally use phpAGI to do all kinds of neat ACD and call routing stuff in our call center.
For more info on AGI, see the official docs.
Edit:
I should probably also explain some basic call flow terminology (from the docs):
Originate: Generates an outgoing call to a Extension/Context/Priority or Application/Data. Example: User clicks a button, Originate a call to their desk phone, when they answer that call, it executes dialplan, or a dialplan application.
Redirect: Redirect (transfer) a call. Example: Agent and Customer are talking, but Manager wants to take over the call. Use Redirect to "take" the call from Agent and ring the Manager.
Dial: (in dialplan only, not AMI) Dial the technology/channel specified. Note that you can only Originate from your .NET application, not Dial.
Can you show your event handler code? It looks like that library would say something like manager.NewChannel += new ManagerEventHandler(new_channel);

Twain always returns TWRC_NOTDSEVENT

I use twain 2.3 (TWAINDSM.DLL) in my application with HP Scanjet 200 TWAIN Protocol 1.9.
My TWAIIN calls are:
OpenDSM: DG_CONTROL, DAT_PARENT, MSG_OPENDSM
OpenDS: DG_CONTROL, DAT_IDENTITY, MSG_OPENDS
EnableDS: DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS
ProcessDeviceEvent: DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT
and as a result of the last call I allways get TWRC_NOTDSEVENT instead of TWRC_DSEVENT.
Could please someone help with this?
Once you use DG_CONTROL / DAT_EVENT / MSG_PROCESSEVENT, all messages from the applications message loop must be sent to the data source for processing. Receiving TWRC_NOTDSEVENT means the forwarded message isn't for the source so the application should process it as normal.
Keep forwarding all messages to the source until you receive MSG_XFERREADY which means there is data to transfer. Once the transfer is finished and you have sent MSG_DISABLEDS that's when you can stop forwarding messages to the source.
Twain is a standard, and when many company implement that standard, not all of them do the same way. Along the way to support Twain, we will learn and adjust the code to support all the different implementations.
I experienced this situation before, and this is my workaround:
Instead of placing (rc == TWRC_DSEVENT) at the beginning of code (will skip the following MSG_XFERREADY processing afterward) you can move the comparison to the end after MSG_XFERREADY processing, so that MSG_XFERREADY is always checked and processed.
(rc == TWRC_DSEVENT) is only to determine if we should forward the window message or not.
I don't know your specific situation. I ran into a similar issue because I called OpenDSM with a HWND/wId which is from another process. You should call OpenDSM with the HWND of
the active window/dialog which is owned by current process.

Asterisk: Record application is generating empty files

User making the call is asked to dial an extension. This is done by 1#playing a prompt with Background and then 2#wait_for_digit. Based on the extension that has been dialed, the destination number is determined and the call is forwarded to that number.
If the called person doesn't not answer, then Playback is used to play a prompt that asks the user to record the voice message; recording the voice message is done with the Record application.
This Record application is always generating empty wav files, size 44 bytes. If I remove the 1#playing a prompt with Background the Record application is generating proper files. If the Background is included, all recordings are empty.
I am using Perl Asterisk::AGI module.
$agi->exec('Answer');
....
.....
$agi->exec('Background', 'en/extra/please-enter-the-extension,n'); # this is the troubling part
my $my_extension = $agi->wait_for_digit(5000);
....
.....
$agi->exec('Playback', 'en/extra/the-party-you-are-calling&en/extra/is-curntly-busy,noanswer');
$agi->exec('Playback', 'en/vm-intro,noanswer');
my $file = 'xyz.wav';
$agi->exec('Record', "$file,0,10,k");
...
...
What should I do to make it work as I want it to?
Thank you.
UPDATE 1:
The same script is working without glitches now. Not sure if something unrelated to the script has changed.
Most likly you have check your codecs. IF you use g729 or g723 and no transcoder,it just can't write in wav format.

Asterisk playback sound file into ConfBridge?

I'm trying to make a conference and play a sound file in the background of the conference. How can I make this possible?
this obviously wouldn't work because the sound file will be played before entering the conference.
exten => s,1,playback(some/soundfile)
same => n,confbridge(1)
Thanks in advance!
Wanted to add my solution here in case anyone ever needs it.
first make a context for the conf bridge in extensions.conf:
[conf-msg]
exten => s,1,ConfBridge(01)
where 01 is the bridge number
Then via the command line you can do:
asterisk -x 'channel originate local/s#conf-msg application Playback file'
Its really as simple as that.
You have create new call,simple method using call files.
http://www.voip-info.org/wiki/view/Asterisk+auto-dial+out
After that you have place one of call legs to your conference like this
Channel: Local/1111#conference
Application: Playback
Data: some/soundfile
Where conference is context to get to ur conference room.
No need do spy or somethign like that,that is wast of time/cpu
See here for a similar question:
Asterisk- How to 'whisper' music using ChanSpy(), or any alternative?
Basically, you want to add a participant that points to a local channel (as above, only enter the channel instead of spying), play your sounds, then hangup.
Same answers, but for many confBridge:
In extension.conf:
[autobridge]
exten => _X.,1,ConfBridge(${EXTEN})
Then, like tgwaste's answer, you could initiate message into conference room 1234, by using originate:
originate local/1234#autobridge application Playback en_US/tt-monkeys
from console or a manager connection,
Or as arheops's answer suggest, by adding a file in outgoing spool dir:
printf "Channel: Local/%d#autobridge\nApplication: %s\nData: %s\n" \
1234 Playback sound/file >/var/spool/asterisk/outgoing/f-$RANDOM
from anything at filesystem level ( with correct permissions, could be shared! :-).

Resources