Recording ChanSpy in Asterisk - asterisk

One call-center needs to play music during phone calls on demand and it should be recorded.
So the auto dialing program makes a call through local channel:
[dialout]
exten => _XXXXXXXXXXX,1,Dial(SIP/${provider}/${EXTEN})
Then when answered it connects an operator:
[operators]
exten => s,1,MixMonitor(${FileName})
same = n,Dial(SIP/${EXTEN})
And then they have a button in questionary which sends to Asterisk AMI commands:
Action: Originate;
Channel: LOCAL/$num#whisper-to-participant;
Application: Playback;
Data: $song;
Async: True;
Here's "whisper-to-participant" context:
exten => _XXX,1,ChanSpy(SIP/${EXTEN},Bq)
So caller and callee both hear music and it's working fine. But I can't get this music be recorded with MixMonitor, I only hear caller and callee.
Can anyone suggest anything to make it work with MixMonitor? Maybe some completely different approach?
Solution
Instead of MixMonitor I use Monitor and it records everything even music barked to ChanSpy. This is the simplest resolution and it works.

You can put user from start to conference, record conference.
After that if you add music into conference, it will be saved
see Confbridge

Related

Asterisk ARI - Pass channel to Stasis before Ringing

My goal
Pass an incoming call directly to Stasis and allow the app to decide whether to play a ringing or busy tone to the caller.
The problem
With my ARI app, if I omit the same => n,Ringing line from my dialplan, the Stasis app returns an error if the caller hangs up. I can have a call hang without any early media, until I pass a channel.play() command, via the ARI.
This solution has 2 issues:
The Stasis app receives a second StasisStart when the caller hangs up, returning a Channel not found error.
There is no command for channel.busy
Does anyone have any suggestions?
My only option that I can currently see is to ensure that all users have voicemail and a busy tone is never played. Not everyone wants / likes voicemail and it is not ethical to answer the call and play a busy tone, without the caller knowing that their call is connected.
Update
Using the following dialplan, I can get this to work in the desired way (plays busy to a user if they're not available), but with an error:
extensions.conf
[public]
exten => _.,1,NoOp()
same => n,Stasis(myStasisApp, ${SIP_HEADER(to)})
same => n,Busy(10)
same => n,Hangup()
myApp.js
// The user is available
channel.ring();
// The user is busy
channel.continueInDialplan();
Error
Another StasisStart is sent when the caller hangs up, followed by:
Unhandled rejection Error: {
"message": "Channel not found"
}
We faced the same problem and lost precious time finding out the reason so I'm sharing the solution here and maybe it will help.
extensions.conf
[public]
exten => _.,1,NoOp()
same => n,Stasis(myStasisApp)
same => n,Hangup()
When Asterisk receive a call, it will start the stasis app.
Create a Bridge.
Add the incomming channel A in this bridge.
Create a new outgoing channel B from your ari app with POST /channels/create.
Add the outgoing channel B in that bridge.
Dial from channel B the destination, where both of the channels
are in the same bridge with POST /channels/{channelId}/dial
Now, you will be able to see a new ARI Dial events with Ringing and Answer.
For the Hangup, you will receive Channels end events with Hangup Cause Code not a text like 17 for busy
Asterisk Hangup Cause Mappings
It's simpler to originate a channel (Asterisk version 13) instead of create and dial (Asterisk version 14) but you will not have the early media or a full control on that channel because it's created by Asterisk and not the ARI app so this channel will start sending event back to ARI when the call start and not before.
Asterisk 14 ARI: Create, Bridge, Dial.
ARI and Channels: Manipulating Channel State
This thread helped us a lot:
Re: ARI: add channel to bridge immediatelly after originate action
.
.
.
Have fun ! and Hope this will help.
/ohammami

How to automatically add users to confbridge asterisk from dialplan?

[play-context]
exten => _X.,1,Answer()
exten => _X.,n,NoOp('Exten:')
exten => _X.,n,NoOp(${EXTEN})
exten => _X.,n,ConfBridge(dconf-${EXTEN}-${STRFTIME(${EPOCH},,%d.%m.%Y-%H:%M:%S)})
exten => _X.,n,Originate(SIP/5678,exten,conferences,100,1)
[conferences]
exten => _X.,1,NoOp(${EXTEN})
exten => _X.,n,ConfBridge(dconf-${EXTEN}-${STRFTIME(${EPOCH},,%d.%m.%Y-%H:%M:%S)})
when i create a new confBridge conference, i want to join some users in it. How i can do it automaticaly? I try this config, but it dont worked. Before this line
exten => _X.,n,Originate(SIP/5678,exten,conferences,100,1)
just does not reach. I do not understand why.
Please, help.
Your channel (your audio when you call the number of the conference) will enter in the conference when it comes to the Confbridge statement in your dialplan. The problem with Confbridge is that once the dialplan has arrived to the Confbridge statement, you will remain there until you exit from it. If you wanted to find there some friends you should have made some previous tasks
Check if the conference is stablished (if there are already other parties in them, see function CONFBRIDGE_INFO) and, if it is, simply add yourself to it
If not, stablish the conference inviting the guys you want to and add yourself to the conference
So, dialplan for conferences is usually not trivial. Let us assume that you do not want to make the first check. So, you are including a guy as you stablish the conference. In order to simplify and to avoid some headaches I am going to use a name for the conference that do not depend on the second at which the dialplan is read (depending on how do you mantain the dialplan your conference could be different from the conference at which you invite your mate), let us suppose that the conference has a name that only depends on the EXTEN dialed. You should do something similar to:
exten => _X,1,Answer()
...
same => n,Originate(SIP/5678,app,ConfBridge,"${EXTEN},rest-of-parameters-for-5678")
... (Check ORIGINATE_STATUS if you do really need your friend)
same => n,ConfBridge(${EXTEN},rest-of-parameters-for-youself)
Here I have used originate with the parameter app. You can, of course, follow the hint of #arheops and use exten with a Local channel. But if you do so, be carefull with the seconds ;).
If you want to stablish automatically the conferences as asterisk starts, consider including some originate statements in cli.conf.
When you do
Confbridge
it now in bridge and not go next extension until you exit bridge.
So you have do Originate BEFORE that or do it in other thread(via Local channel) in parallel.

Asterisk - playing music whilst originating a call

I'm using a cloud-based Asterisk server as my PBX. At my current location, the Internet is rather shaky, but cell phones are reliable and commonplace. However, international cell calls are expensive, VOIP calls are much cheaper.
So, I came up with a script in Asterisk which dials my local cell phone:
exten => _abcd.,1,NoOp(-- Making outbound call to number ${EXTEN:4} --)
same => n,Answer()
same => n,Wait(1)
same => n,Originate(SIP/+86[my_cell_no]#[voip_provider],exten,incoming_remote,##${EXTEN:4})
same => n,Hangup()
Let's say I want to call a UK mobile number, +4477something. I would use my softphone to dial abcd+4477something. The script above runs, makes a call into my local cell phone. As soon as I answer, it jumps into another extension _##. which dials the outbound number, and connects the two together.
It works perfectly. However, whilst I'm waiting for the local cell to connect, I've got silence on the line. I'd quite like to play music... but I can't use the MusicOnHold() application, because it just sits there & does nothing until I hang up!
I can't add any "DIAL" style commands (i.e. "m") to the Originate command because it doesn't support them.
Is there any known way of playing (one of) the MusicOnHold channels asynchronously whilst the rest of my dialplan gets on with it?
Would the AGI command SET MUSIC do what I wanted?
e.g.
exten => _abcd.,1,NoOp(-- Making outbound call to number ${EXTEN:4} --)
same => n,AGI(turn_music_on.sh)
same => n,Answer()
.....etc.
I'm using Asterisk 1.8, if a newer version fixes/changes the MusicOnHold behaviour, then that will be the accepted answer (but the documentation seems to suggest it's the same).
You can call to Local channel(dialplan). After that in dialplan you can use m of dial command.
https://www.voip-info.org/wiki/view/Asterisk+local+channels
same => n,Originate(Local/[my_cell_no]#out/n,exten,incoming_remote,##${EXTEN:4})
[out]
exten => _X.,1,Dial(SIP/+86${EXTEN}#[voip_provider],,m)

Asterisk call transfer on DAHDI channells

All channels on Asterisk configured as DAHDI channels.After customer make payment I want to transfer the customer to the representative who interact customer before.
I try to make it by Dial() command. This is the dialplan
exten => s,1,Set(TRFNUM=${CALLERID(num)})
exten => s,2,Set(TRFNAME=${CALLERID(name)})
exten => s,3,AGI(agi://192.168.7.20/customivr)
exten => s,4,Dial(DAHDI/1/${TRFNUM}&DAHDI/2/${TRFNUM}&DAHDI/3/${TRFNUM}&DAHDI/4/${TRFNUM}&DAHDI/5/${TRFNUM}&DAHDI/6/${TRFNUM}&DAHDI/7/${TRFNUM}&DAHDI/8/${TRFNUM},30)
exten => s,5,Hangup
For example: Call comes to DAHDI/1 after the payment DAHDI/1 dial all channels one them Answer the others Hangup. DAHDI/1 bridge call by with DAHDI/2. However, although Customer and representative close phones, Channels do not Hangup. They stay Busy.
Where do i make mistake. I should hangup call channels or find another way to transfer.
It seems to be configured correctly,
I think your AGI script hangup the call when he finishes his work,
It can happen if you have $agi>hangup in the end,
or if you make any outputs in the scripts (echo, print_r, etc...),
even empty spaces output can cause this behavior,
another thing you can try is make the Dial command from the agi itself using:
agi->exec("Dial","options");

Asterisk auto Call recording

We are running asterisk with 8 port FXO. FXO connects to our old PBX (Samsung Office Serv 100).
Now we want to record all calls routed through FXO (if it was dialed to outside or comming from outside).
Is there a simple way to do this?
Are you running plain Asterisk? If so you can modify your dial plan to start 'monitoring' the channel, which will record the call.
The monitor command's documentation: http://www.voip-info.org/wiki/view/Asterisk+cmd+monitor
Just for the sake of completion, here's the documentation:
[root#localhost ~]# asterisk -rx 'core show application monitor'
-= Info about application 'Monitor' =-
[Synopsis]
Monitor a channel
[Description]
Monitor([file_format[:urlbase],[fname_base],[options]]):
Used to start monitoring a channel. The channel's input and output
voice packets are logged to files until the channel hangs up or
monitoring is stopped by the StopMonitor application.
file_format optional, if not set, defaults to "wav"
fname_base if set, changes the filename used to the one specified.
options:
m - when the recording ends mix the two leg files into one and
delete the two leg files. If the variable MONITOR_EXEC is set, the
application referenced in it will be executed instead of
soxmix and the raw leg files will NOT be deleted automatically.
soxmix or MONITOR_EXEC is handed 3 arguments, the two leg files
and a target mixed file name which is the same as the leg file names
only without the in/out designator.
If MONITOR_EXEC_ARGS is set, the contents will be passed on as
additional arguments to MONITOR_EXEC
Both MONITOR_EXEC and the Mix flag can be set from the
administrator interface
b - Don't begin recording unless a call is bridged to another channel
i - Skip recording of input stream (disables m option)
o - Skip recording of output stream (disables m option)
By default, files are stored to /var/spool/asterisk/monitor/.
Returns -1 if monitor files can't be opened or if the channel is already
monitored, otherwise 0.
And here's a sample way you can use it:
; This fake context records all outgoing calls to /var/spool/asterisk/monitor in wav format.
[fake-outgoing-context]
exten => s,1,Answer()
exten => s,n,Monitor(wav,,b)
exten => s,n,Dial(DAHDI/g0/${EXTEN})
exten => s,n,Hangup()
Obviously you'd have to make changes to my code, but hopefully that gives you a good idea.
A real life example is
exten => _87X,1,NoOp()
exten => _87X,n,MixMonitor(${UNIQUEID}.wav,ab)
exten => _87X,n,Dial(SIP/${EXTEN},45)
exten => _87X,n,StopMixMonitor()
exten => _87X,n,Hangup()
It's good practise to always have NoOp - the first rule must start with 1, this way you can interchange the rules with the n step any way you want.
It's always best to use MixMonitor as opposed to Monitor - Monitor only records inbound or outbound audio - MixMonitor uses both.
Also wav is quite a good choice as a format - I also use a script to transform the wav files to OGG at the end of the day - the best compromise between size / quality and licensing issues.
With regards to the arguments
a is append
b is bridge (good for production - it will only record when the call is answered - not good for debugging)
With regards to StopMixMonitor(), I'm just being thorough, but for examples there are cases in which you would like to stop the recording, for example:
...
exten => _39[5-9],n,Dial(SIP/${EXTEN},45)
exten => _39[5-9],n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavailable)
exten => _39[5-9],n(busy),NoOp()
exten => _39[5-9],n,StopMixMonitor()
exten => _39[5-9],n,Voicemail(${EXTEN},u)
exten => _39[5-9],n,Hangup()
exten => _39[5-9],n(unavailble),NoOp()
exten => _39[5-9],n,StopMixMonitor()
exten => _39[5-9],n,Hangup()
...
In this example, you would stop the recording of the voice mail interaction.
Hope this will bring some light on the matter.
Depending on the specifications of your Asterisk box you might find this hack useful too. Create a rather large ramdisk and mount /var/spool/asterisk/monitor to it. That way Asterisk records to memory not disk. Then write a script under cron to move the recordings to permanent storage every 15-30 minutes or so.

Resources