asterisk dialplan context clarifications - sip

I have been learning asterisk dialplan and I have created a very simple IVR menu.I would like someone to verify that what I have created is correct.I want to create a very simple IVR with 2 menu levels and an exit option.
[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)
exten => 9,1,Hangup()
[main-menu]
exten => 456,1,Answer()
exten => 456,n,Background(main-menu)
exten => 3,1,Playback(digits/3)
exten => 3,n,Goto(incoming,456,1)
exten => 4,1,Playback(digits/4)
exten => 4,n,Goto(incoming,456,1)
exten => 9,1,Hangup()
I have created 2 context's above
[incoming] - to handle incoming calls
[main-menu] - A menu option.
In the incoming context.I call the Answer() application when the extension is '123' Then it executes the background (main-menu).
if the user presses '1' it plays '1' and goes back to 123 priority '1'
if the user presses '2' it plays '2' and goes back to 123 priority '1'
if the user presses '9' it hangs up.
Similarly in [main-menu]
do I need an answer() in this context also?
I am just beginning to understand the dialplan and I am a bit confused at the moment.
So based on you suggestions my updated dialplan would look something like this.
[incoming]
exten => 123,1,Answer()
same => n(menuprompt),Background(main-menu)
exten => 1,1,Playback(digits/1)
same => n,Goto(menuprompt)
exten => 2,1,Playback(digits/2)
same => n,Goto(menuprompt)
exten => 9,1,Hangup()
[main-menu]
exten => n(menuprompt),Background(main-menu)
exten => 3,1,Playback(digits/3)
same => n,Goto(menuprompt)
exten => 4,1,Playback(digits/4)
same => n,Goto(menuprompt)
exten => 9,1,Hangup()
Thanks for the suggestions and explanations.But I have one question.
1) "main-menu" that is passed to the Background is is sound file apparently.In case of [incoming ] I want that to say something like
"press 1 to play 1"
"press 2 to play 2"
"press 9 to hangup"
where as in case of [main-menu] I want it to say something like
"press 3 to play 3"
"press 4 to play 4"
"press 9 to hangup"
Do I have to record that file.? How does that work?
Thanks in advance.

You're close, but not quite.
Think of contexts as physical boxes. You can't go through the walls in the box. So, "labels" and extensions only apply to what is in that one particular box / context.
In your updated dialplan, you would need to specifically Goto the context/extension/priority to get from one context to the other. That way the dialplan knows you aren't trying to refer to something inside the context it is already operating in.
With regards to message prompts you are playing, yes, you'll need to record those. MP3 format is the easiest to work with from the user perspective, but it puts a bit more load on the PBX. In this day and age of multi core gigahertz CPUs, I rarely worry about that.
If this is going to be a publicly facing system, consider your menu recordings to be the most important part of your system, from the customer POV. Messages with poor quality, low volume, difficult accents and such will "convince" your customer that your IVR is "too much work" to use.

Your [incoming] context does exactly what you think it does.
You would only need to Answer() the line once ... before you start sending sound to the customer. So you would only need to Answer() in [main-menu] if you had not done it before.
Here is a slight re-write of [incoming] that would be a bit "better" in terms of readability and goof-proofing.
[incoming]
exten => 123,1,Answer()
same => n(menuprompt),Background(main-menu)
exten => 1,1,Playback(digits/1)
same => n,Goto(menuprompt)
exten => 2,1,Playback(digits/2)
same => n,Goto(menuprompt)
exten => 9,1,Hangup()
"Same" does exactly what it sounds like; "use the same extension as the line above". If you are doing large dialplans where you are doing a bit of cut-paste-tweak between different sections, such as IVRs, using "same" saves you from making an error with the extension number.
The "(menuprompt)" is called a label, and you can Goto labels within the same context, which absolves you of having to count "n"'s to figure out what priority number to use.
Further reading: https://wiki.asterisk.org/wiki/display/AST/Contexts,+Extensions,+and+Priorities

Related

Asterisk hangup-handler

I am new to Asterisk.
I am trying to define a hangup-handler for a survey.
The survey needs to be activated after the agent hangs up the call.
I put that to my [macro-queue] context,
exten => s,n,ExecIf($["${HASH(queueInfo,survey)}" != "1" & "${isfinishcall}" !="1"] ?Set(CHANNEL(hangup_handler_push)=goto-anket,s,1(${HASH(queueInfo,survey)})))
and I defined that for survey,
[goto-anket] exten => s,1,Noop(Ankete Geldi) exten => s,2,Agi(anket.php) exten => s,3,Return()
but when the agent hangs up the call is not activated. What should I do?
its not worked. because change is closed
you need to do that via queue with option 'C'
example
exten => 1000,n(qcall),Queue(1000,tc,,${QAANNOUNCE},${QMAXWAIT},${QAGI},,${QGOSUB},${QRULE},${QPOSITION})

How can i transfer repeated call to same queue member in asterisk

I am using queue and i want to map one caller to one executive.As if i call in the queue and you receive my call then next time if i call in the queue so call will automatically forwarded to you not other members of queue. Is there any option in queue configuration for do that...?
You need do something like this
exten => _X.,1,Set(ext=${ODBC_check_info(${CALLERID(num)})})
exten => _X.,2,GotoIF($[ "${ext}" != "" ]?from-internal,${ext},1); if match, call ext
exten => _X.,3,Goto(from-psnt,${EXTEN},1); if nto match,go default route
Sure you also need define odbc function check_info and setup odbc.
Also need write some info who answered to some table(using queue_log or dial cmd on-answer-macro)
http://www.voip-info.org/wiki/view/Asterisk+func+func_odbc

Asterisk - Record calls using MixMonitor for outbound calls

I have a macro set up to record inbound calls on an extension:
[macro-DialStartMonitor]
; Calculate the time of the call from "epoch time", format it into yyyy-mm-dd and add the PhoneExt. at the end
exten => s,1,Set(MONITOR_FILENAME=${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-FROM-${CALLERID(num)}-TO-${ARG1})
same => n,MixMonitor(${MONITOR_FILENAME}.wav,b)
exten => 1001,1,noop(Dialing ${PEX_ONE})
same => n,Macro(DialStartMonitor,${PEX_ONE})
same => n,Dial(SIP/${PEX_ONE},30,mTt)
same => n,Playback(vm-nobodyavail) ; Play "no one's available"
same => n,Hangup()
exten => 1002,1,noop(Dialing ${PEX_TWO})
same => n,Macro(DialStartMonitor,${PEX_TWO})
same => n,Dial(SIP/${PEX_TWO},30,mTt)
same => n,Playback(vm-nobodyavail) ; Play "no one's available"
same => n,Hangup()
Thus, when I make a call from 1002 to 1001, the recording is saved to /var/spool/asterisk/monitor with a format like this example "20140106-122313-FROM-1002-TO-PExten1001.wav"
I need to record the outbound call that originated from 1002 as it's own separate file - that is, when a call is made from 1002 to 1001, 2 recordings are made, one is an inbound recording for 1001(which is the code above) and one is an outbound recording for 1002(which is what this question is about).
Do I have to write a separate context for both the extensions? Or is there another method?
Thanks in advance.
You can't do 2 monitor on SAME channel.
To do what you want you have 2 variants
1) Create script on hangup which will copy file(recommended way)
2) Dial via Local/soemexte#somecontext/n and create enother monitor inside somecontext.

Setting CDR fields in "connected" macro

I am using Asterisk's queue app. When caller's call is picked up by queue member I want to set some CDR variables.
But problem is, that the "connected" macro is executed in queue member's channel (It should be caller's channel in my opinion)
exten => XXX, n,Queue(sales,tc,,,,,QueueConnected)
[macro-QueueConnected]
exten => s,1,NoOp()
exten => s,n,Set(CDR(somevar)=someval)
I can use "c" option for queue and the dialplan will continue after caller or member hangup, but it is too late to setup CDR values, because it is already emitted.
Can anybody help me with this, thank you.
So I figured this out by using HangupHandlers
exten => XXX, n,Set(CHANNEL(hangup_handler_push)=_hnd,s,1);
exten => XXX, n,Queue(sales,tc,,,,,QueueConnected)
[_hnd]
exten => s,1,NoOp()
exten => s,n,Set(CDR(somevar)=someval)
Works like a charm

Caller ID in Asterisk for user identification

I am new to Asterisk, so forgive me if this question has an obvious answer that I have simply overlooked.
I am making a mix between a personal ads and a voicemail service, where I want each user to be able to submit an ad that others can respond to by recording messages that go into this users inbox. My original thought was to base this purely on the CALLERID(num) value, but quickly discovered that this is a bit unreliable. Sometimes when I would call in it'd say anonymous, other times it would give me a bunch of zero's, other times it would show me my real phone number, and once it actually gave me just random digits. I do have a wait call after answering but before my first soundf ile is triggered, in my pickup context. I am wondering what the best way to approach this is? Do I ask the user to enter their phone number, and then generate a code based upon this that will then serve as a password when you call back? Do I attempt to use CALLERID(num) to detect returning users, or is this not adviseable from a security perspective?
Preferably, I would like to avoid using a code altogether but I am told that it is relatively easy to spoof phone numbers to hack into someone else's inbox. Note that I do not plan to allow direct SIP calls, only through a PSTN/SIP provider where the IP address is on a whitelist. Any tips on how to approach this would be highly appreciated. Basically I want to make it as easy as possible for my users, but maintain high security.
I also wanted to know whether there is a function to check if a string contains only digits? This would be useful as a sanity check before I look up the phone number in the MySql database, if I do decide to use CALLERID(num) in this way.
My very basic, and unfinished dialplan is below:
[verify]
exten => blastbay,1,Answer(1000)
; A few simple sanity checks, but not very good ones.
same => n,GotoIf($["${CALLERID(num)}" != "0000000000"]?nextcheck)
; If we have only zero's, try waiting another second.
same => n,Wait(1)
same => n,GotoIf($["${CALLERID(num)}" = "0000000000"]?rejected)
same => n(nextcheck),GotoIf($["${CALLERID(num)}" = ""]?rejected)
same => n,GotoIf($["${CALLERID(num)}" = "anonymous"]?rejected)
same => n,GotoIf($["${CALLERID(num)}" = "unavailable"]?rejected)
same => n,GotoIf($["${CALLERID(num)}" = "protected"]?rejected)
same => n,GotoIf($[${LEN(${CALLERID(num)})}<5]?rejected)
same => n,Goto(welcome,welcomespeech,1)
same => n(rejected),Playback(/usr/phone/rejected)
same => n,Hangup()
[welcome]
include => mainmenu
exten => welcomespeech,1,BackGround(/usr/phone/welcome)
same => n,Goto(mainmenu,menuspeech,1)
[mainmenu]
exten => menuspeech,1,BackGround(/usr/phone/mainmenu)
same => n,WaitExten(5)
exten => 1,1,Goto(information,infospeech,1)
exten => i,1,Goto(menuspeech,1)
exten => t,1,Goto(menuspeech,1)
[information]
exten => infospeech,1,BackGround(/usr/phone/information)
same => n,Goto(mainmenu,menuspeech,1)
exten => #,1,Goto(mainmenu,menuspeech,1)
exten => i,1,Goto(mainmenu,menuspeech,1)
One command that is often overlooked is the "Authenticate" command... so you could build a mechanism that assigns a user a number-based UID, and then a PIN. Drop the PIN into a file where the name is the UID, and then when they call in, READ their UID, Authenticate(uid_file_name), and if they enter the correct PIN via Authenticate, let them have access.
I am making a mix between a personal ads and a voicemail service, where I want each user to be able to submit an ad that others can respond to by recording messages that go into this users inbox.
Therefore you could use Record(), Playback() and Voicemail().
Record() to record the Ad,
Playback() the Ad,
Voicemail() for the Users to record their Voicemail
If you want more Access Control, i would recommend to use PHP AGI or
use the AstDB.
Yes, it's easy to spoof a Number, for access control, something like an Access Code,
with Read you read DTMF Input as a Variable, maybe combined with a CallerID Number based filter, sounds like an good idea.
I also wanted to know whether there is a function to check if a string contains only digits?
You could use REGEX for this, ie. in a macro:
; Arg1: CALLERID(num)
[macro-dblookup]
exten => s,1,Set(isnumber=${REGEX("[0-9]" ${ARG1})})
exten => s,2,GotoIf($["${isnumber}" = "1"]?4)
exten => s,3,MacroExit()
exten => s,4,NoOp("Do something with number here")
exten => s,5,NoOp("...Db Lookup...")
In the Dialpan you can call the macro-dblookup like this:
exten => 012345678,1,Noop("...")
exten => 012345678,n,Macro(dblookup,${CALLERID(num)})