Asterisk, Goto+Hungup - asterisk

There is an extension, for which I need a random sound file to be played, and once it's played the call should be hung up. I have the below dialplan which plays, for example, the 2nd playback and then 3rd one is played etc., but it should hangup after playing back one sound file
exten => 123.,7,Goto(${RAND(8,12)})
exten => 123.,8,Playback(/var/lib/asterisk/sounds/customer_Menu1)
exten => 123.,9,Playback(/var/lib/asterisk/sounds/customer_Menu2)
exten => 123.,10,Playback(/var/lib/asterisk/sounds/customer_Menu3); after playback it supposed rejected..
exten => 123.,11,Playback(/var/lib/asterisk/sounds/customer_Menu4)
exten => 123.,12,Playback(/var/lib/asterisk/sounds/customer_Menu5)
exten => 123.,13,Hangup()
exten => 123.,14,Hangup(34)
How can I make this work; calling, playing only one random menu and hanging up?

Just give the hangup command a priority label and add a Goto() pointing to it after playing each item.
Also:
if you want to use pattern matching for an extension (I assume that's why you have a dot after 123) you should prefix it with an underscore
same can be used in place of exten => ... for the extension when you're repeating the same thing
n can be used for the next priority so you don't have to worry about keeping all the numbers straight
Now if we get rid of the priority numbers, what do you use in place of Goto(${RAND(8,12)})? More labels:
[mycontext]
exten => _123.,1,NoOp("start of context")
; ...
same => n,Goto(menu${RAND(1,5)})
same => n(menu1),Playback(/var/lib/asterisk/sounds/customer_Menu1)
same => n,Goto(goodbye)
same => n(menu2),Playback(/var/lib/asterisk/sounds/customer_Menu2)
same => n,Goto(goodbye)
same => n(menu3),Playback(/var/lib/asterisk/sounds/customer_Menu3)
same => n,Goto(goodbye)
same => n(menu4),Playback(/var/lib/asterisk/sounds/customer_Menu4)
same => n,Goto(goodbye)
same => n(menu5),Playback(/var/lib/asterisk/sounds/customer_Menu5)
same => n(goodbye),Hangup(34)
Or, more simply, use the RAND() function to choose the name of the file to play:
[mycontext]
exten => _123.,1,NoOp("start of context")
; ...
same => n,Playback(/var/lib/asterisk/sounds/customer_Menu${RAND(1,5)})
same => n,Hangup(34)

Should be something like this:
exten => _123.,7,Set(FILES=customer_Menu1:customer_Menu2:customer_Menu3)
same => n,Playback(${CUT(FILES,:,${RANDOM(1,3)}); CUT will get nth argument delimited by :
same => n,Hangup(34)
Or like miken32 show you if your files are always same name.
Also nice idea is move configure variables like FILES in [general] section or special file included in code.
You DO NOT need /var/lib/asterisk/sounds/ before every file. Just check that in your /etc/asterisk/asterisk.conf sound path is /var/lib/asterisk/sounds(default).

Related

Asterisk extension, conditional execution?

I have an this extension in file /etc/asterisk/extensions_custom.conf:
exten => _XXXX,1,NoOp("-- from internal custom --")
exten => _XXXX,n,Set(CURL_RESULT=${CURL(https://your.domain.com/sip_webhook?callid=${EXTEN}&sourceid=${CALLERID(num)})})
exten => _XXXX,n,Wait(3)
exten => _XXXX,n,Dial(PJSIP/${EXTEN},60)
exten => _XXXX,n,Hangup()
The second line sends a request to a webhook in my server and stores the response in CURL_RESULT
I want to execute Dial only if CURL_RESULT was successful is there any way to achieve conditional execution of an extension?
something like:
if(CURL_RESULT=="OK")
exten => _XXXX,n,Dial(PJSIP/${EXTEN},60)
else
exten => _XXXX,n,Hangup()
Yes, as arheops indicated, this is actually a common built-in concept in the dialplan: conditional executing and conditional branching.
There are a lot of ways you could this - to give you some ideas:
#1: Conditional execute if true
exten => _XXXX,1,ExecIf($["${CURL_RESULT}" = "OK" ]?Dial(PJSIP/${EXTEN},60))
same => n,Hangup()
#2: Conditional branch if false
exten => _XXXX,1,GotoIf($["${CURL_RESULT}" != "OK" ]?exit)
same => n,Dial(PJSIP/${EXTEN},60)
same => n(exit),Hangup()
#3: Conditional branch if true/false:
exten => _XXXX,1,GotoIf($["${CURL_RESULT}" = "OK" ]?dial:exit)
same => n(dial),Dial(PJSIP/${EXTEN},60)
same => n(exit),Hangup()
That last example doesn't add anything in this case, but providing a true and false label is often useful.
If you want a true If/Else application in Asterisk, that works similar to in conventional programming languages, you can use the If module: https://github.com/InterLinked1/phreakscript/blob/master/apps/app_if.c (this has since been merged into Asterisk, you don't need to patch separately).
It's not currently included in mainline Asterisk so you'd need to drop that into your source, compile, and reinstall.
With that, you could do something like:
same => n,If($["${CURL_RESULT}" = "OK" ])
same => n,Dial(PJSIP/${EXTEN},60)
same => n,NoOp(${DIALSTATUS})
same => n,Else()
same => n,Playback(goodbye) ; do something else
same => n,EndIf()
same => n,Hangup() ; something after both
Each type of conditional syntax tends to work slightly nicer than some of the others in particular circumstances.

Asterisk block incoming call from specific country only

I am trying to make a dial plan to block incoming call coming from let say bangladesh where country code is 88
Here is my dial plan
exten => _X.,1,NoOp(${CALLERID(num)})
same => n,Set(regx=^(88)[0-9]$)
same => n,GotoIf($[${REGEX("${regx}" ${CALLERID(num)})} = 1]?blacklisted,s,1)
same => n,Dial(SIP/8.8.8.8/${EXTEN}
[blacklisted]
exten => s,1,Wait(9)
what i want to do is anything that comes from 88 should be sent to blacklist. At the moment if I test call with Caller ID 88 it works but if the call comes from 88XXXXXXX this does not work what can I do to make my dial plan block anything coming from 88XXXXXXXX to goto black list
Why do you use the complex REGEX function? Just do something like that:
exten => _X.,1,NoOp(CallerID is: ${CALLERID(num)})
exten => _X.,n,Set(number=${CALLERID(num)})
exten => _X.,n,ExecIf($[${number:2} = 88],Hangup())
exten => _X.,n,NoOp(Call is being continued)
This will save the callerid num into the "number" variable. Then it will check if the first 2 characters of the variable are equal to 88. If so, the call will be hung up. You can also use GoToIf instead of ExecIf if you want to send the blacklisted call to a specific context where you want to do something else with it.
Asterisk dialplan is regexp itself. Why you use other regexp?
exten => _X.,1,NoOp(${CALLERID(num)})
same => n,Gosub(cid-blacklist,${CALLERID(num)},1)
same => n,Dial(SIP/8.8.8.8/${EXTEN}
[cid_blacklist]
exten => _88.,1,Noop(bangladesh)
same => n,Wait(100)
; this works only when not found match in context.
include=> cid_blacklist_not_found
[cid_blacklist_not_found]
exten => _X.,1,Return;not found in cid blacklist

Asterisk "monitor" command records calls but throws away recorded files on premature hangup

I am using the "monitor" command to record full calls. This works well, but only when the user goes through the entire callflow. I tried monitoring the recorded file size as the call progresses. Once the call starts, the file sizes start increasing (of both the "in" and "out" sides of the call). However, if the user hangs up prematurely in the middle of the call, whatever has been recorded thus far is inexplicably dropped and stubs (44 bytes) are left in its place. Any insight into why this behavior occurs will be appreciated.
I am reproducing a snippet from the dialplan I used in my extensions.conf file below:
exten => 7611,1,Answer()
exten => 7611,n,Playback(/var/lib/asterisk/sounds/custom/transferring_with_record_wa rning)
exten => 7611,n,Set(GROUP()=outgoing)
exten => 7611,n,NoOp(The current group count : ${GROUP_COUNT(outgoing)})
exten => 7611,n,GotoIf($[${GROUP_COUNT(outgoing)}>1]?15)
exten => 7611,n,Set(GLOBAL(current_timestamp_7611)=${STRFTIME(${EPOCH},GMT+1,%s)})
exten => 7611,n,Set(GLOBAL(current_full_format_timestamp_7611)=${STRFTIME(${EPOCH},G MT-8,%d%m%Y_%H%M%S)})
exten => 7611,n,NoOp(The current timestamp : ${current_timestamp_7611})
exten => 7611,n,NoOp(The last timestamp : ${last_timestamp_7611})
exten => 7611,n,GotoIf($[(${last_timestamp_7611}+20>${current_timestamp_7611})]?15)
exten => 7611,n,NoOp(All cases passed)
exten => 7611,n,Ringing()
exten => 7611,n,Wait(2)
exten => 7611,n,Monitor(wav,HALEF_audio_ext_7611_${current_full_format_timestamp_761 1})
exten => 7611,n,Dial(SIP/1200#JVXML97,,XgF(default^7611^14))
exten => 7611,n,Set(GLOBAL(last_timestamp_7611)=${STRFTIME(${EPOCH},GMT+1,%s)})
exten => 7611,n,Hangup()
exten => 7611,n,Ringing()
exten => 7611,n,Wait(2)
exten => 7611,n,Playback(/var/lib/asterisk/sounds/custom/busy_later)
exten => 7611,n,Wait(1)
exten => 7611,n,Hangup()
I understand that the "record" command has a "k" parameter which keeps the recorded file upon hangup, but I'm not able to find any similar functionality with the Monitor command. (I'd use "record", but I'd like to record the full call (duplex) and do it automatically, without any user input requirement).
Thanks!
Use MixMonitor command.
Check you have permissions needed for write files.
Check debug if you unsure.
PS. using diaplan WITH n, without labels and goto to EXACT priority is very bad practice, can result hard-catchable bugs. Using GLOBAL variables without need also not so nice idea.

Can't combine DongleStatus with different dial plans

We have 2 two major mobile carriers in our country - (1) beginning with 818927, 818937, 818929 and (2) beginning with 818917, 818919, 818987, 818989.
I have 4 usb modems (huawei) and I want 2 different lines to be used for each of those mobile carriers.
I am using DongleStatus because 2 simultaneous calls must be allowed on the same prefix (e.g. when there's two the same SIP agents are calling the same direction e.g. both of them trying to call two different numbers from 818927* range simultaneously)
Here I mention the extensions configuration which doesn't works!
But if you will remove all exten lines and only 1 of them will be remaining, then the whole DongleStatus script mentioned bellow works perfectly (it allows to use 4 lines subsequently by 4 SIP agents simultaneously)
I need your help to find a mistake in mentioned bellow configuration or your suggestion on alternate ways to achieve the same goal. I'm relatively new to asterisk, and I would appreciate not over-complicated answers.
; buklau
exten => _818927XXXXXXX,1,DongleStatus(GSM-001,Dongle0_Status)
exten => _818937XXXXXXX,1,DongleStatus(GSM-001,Dongle0_Status)
exten => _818929XXXXXXX,1,DongleStatus(GSM-001,Dongle0_Status)
exten => _818917XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
exten => _818919XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
exten => _818987XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
exten => _818989XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
same => n,DongleStatus(GSM-002,Dongle1_Status)
same => n,DongleStatus(GSM-003,Dongle2_Status)
same => n,DongleStatus(GSM-004,Dongle3_Status)
same => n,GotoIf($[${Dongle0_Status} = 2]?dongle0dial:dongle1check)
same => n(dongle0dial),Dial(Dongle/GSM-001/${EXTEN:2},60,tT)
same => n,Hangup
same => n(dongle1check),GotoIf($[${Dongle1_Status} = 2]?dongle1dial:dongle2check)
same => n(dongle1dial),Dial(Dongle/GSM-002/${EXTEN:2},60,tT)
same => n,Hangup
same => n(dongle2check),GotoIf($[${Dongle2_Status} = 2]?dongle2dial:dongle3check)
same => n(dongle2dial),Dial(Dongle/GSM-003/${EXTEN:2},60,tT)
same => n,Hangup
same => n(dongle3check),GotoIf($[${Dongle3_Status} = 2]?dongle3dial:utel)
same => n(dongle3dial),Dial(Dongle/GSM-004/${EXTEN:2},60,tT)
same => n,Hangup
This part:
exten => _818989XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
same => n,DongleStatus(GSM-002,Dongle1_Status)
is equal to
exten => _818989XXXXXXX,1,DongleStatus(GSM-003,Dongle2_Status)
exten => _818989XXXXXXX,2,DongleStatus(GSM-002,Dongle1_Status)
So it will not work with any other patern used above. If you need part be for all above, use something like
exten => _8189XXXXXXXXX,2,DongleStatus(GSM-002,Dongle1_Status)
Hint: You always can ask asterisk show how it understand dialplan, for that do
asterisk -rx "dialplan show number#context"

Waiting for extra digit when it's clear that there's no other matching rule

I'm a beginner on Asterisk, but already have my PBX working connected to the PSTN. The issue I'm having is that I have this rule
exten => _*X.*,1,Log(DEBUG, Calling through provider one to ${EXTEN:1:-1})
same => n,Dial(SIP/${EXTEN:1:-1}#oneProvider,60)
There are no other extensions that start with *. What I want to achieve is to dial out as soon as the second * is pressed (and there's nothing the user can press to go to a valid extension), right now it waits a few seconds and dial. I also tried adding ! at the end of the extension, but nothing changed.
Am I missing something? Is this feasible?
Thanks!
This task is not doable in current asterisk.
It will not work beacuase * matched .(dot) in your dialplan.
Except dialplan like this(very ugly one beacuase it will go dialplan for every new digit)
[originalcontext]
exten => *,1,Goto(collect_number,s,1)
[collect_number]
exten => s,1,WaitExten(); wait for single digit
exten => *,1,Set(stars=${stars}*);save stars
exten => *,2,GotoIF($[ "${stars}" == "**" ]?dial,1); if 2 star already,go dial.
exten =>_X,1,Set(digits=${digits}${EXTEN});save digits
exten => _.,3,WaitExten(); wait enother input;
exten => _.,4,Goto(dial,1); go dial if no new digits
exten => dial,1,Dial(SIP/${digits}#oneProvider,60)
Correct solution - use Read application and ask user use # to end number instead of *.
You also can try dialplan like this:
exten => _*X*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXX*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXXX*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXXXX*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXXXXX*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXXXXXX*!,1,Goto(dial,${EXTEN:1:-1},1)
exten => _*XXXXXXXX*!,1,Goto(dial,${EXTEN:1:-1},1); continue upto max number length
[dial]
exten =>_.,1,Dial(SIP/${EXTEN}#oneProvider,,);
But i not fully sure that will work. If works, will be less load(but more lines)

Resources