Friday, May 8, 2009

Asterisk PBX System Install - 09 Voicemail Macros

Issue:
Configuring Voicemail in Asterisk

Quick/Visual/Learning:
Voicemail is an important part of any phone system and it seems to work amazingly well in Asterisk with very little configuration.

First you need to define the mailboxes in the voicemail.conf file.
The sample configuration file has a lot of stuff in it but want we need to configure is towards the bottom of the file.

In the sample file there is an example under the context of [default] that looks like:
[default]
1234 => 4242,Example Mailbox,root@localhost

The 1234 part is the extension of the phone
4242 is the password (this can be updated by the user from his phone)
“Example Mailbox” is the name of the mailbox owner and is used in dial by name directory lookups (see page 156 of the book)
root@localhost is the email address where you want to send a copy of any voicemail messages.

Note for more information about sending to a pager etc. look at the book on page 155.

For my use I need to add voicemail for myself. I will do this under the context of [default] and not [internal] (I orignally thought that my voicemail context should match my phone extension context but not true apparently.) I discovered, if I changed the context here, the message waiting light on my phone did not work. (I think the fix for that is to change the mailbox=207 in the sip.conf file to mailbox=207@internal, more on that below)

I add the following line to the voicemail.conf file.

207 => 1234,Jimmy Ezell,jezell@company.com

Pretty simple.
For each additional mailbox I just need to add another line under the [default] context.

Note - The ability to forward voice mail messages to a email account is great but if you need to look for a voicemail message they are stored in: /var/spool/asterisk/voicemail/ContextName/Extension/INBOX

Now we need to make some changes to the extension.conf dialplan file to make use of the voicemail.

To do this we use the voicemail() application like this:
Voicemail(207@default,u)
This will send callers to my voicemail and play the unavailable message. That is what the u means. But what if I want to play the busy message? Use a b instead of the u.

What I really want is for Asterisk to play correct message depending on if I am busy (on the phone) or unavailable (away from my desk). That requires a little programming and that is what we are going to look at now.

First I will show you what gets added and then explain it. Then we will look at a way of creating a macro so that we do not have to type this for each one of our phone extensions.

[internal]
exten => 207,1,Dial(SIP/207,10)
exten => 207,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => 207,n(unavail),Voicemail(207@default,u)
exten => 207,n,Hangup()
exten => 207,n(busy),Voicemail(207@default,b)
exten => 207,n,Hangup()


The first part you should know. There is the context of [internal] and the command to dial the phone.
You need to know that if Asterisk fails to connect to my phone it saves the reason in a variable called DIALSTATUS. This happens automatically.

Now if the phone does not pickup we go to the next line with the GotoIf command. The GotoIf command is going to allow us to control what happens next.
GotoIf(Expression?TrueDestination,FalseDestination)
Expression is going to be a comparison test follow by a question mark.
TrueDestinaiton and FalseDestination is going to be a lable that points to another line of the dialplan.

Expressions look like this $[expression], where the expression might be comparing two things like, is DIALSTATUS equal to BUSY? Or something like:
$[DIALSTATUS = “BUSY”]. The BUSY in quotes is what I am checking for.

This expression is not quite right yet. Remember that DIALSTATUS is a variable and we have to write it like this to get the contents of a variable - ${DIALSTATUS}.

So now after replacing DIALSTATUS with $[DIALSTATUS]we have:
$[${DIALSTATUS} = “BUSY”]
This is the expression that will compare the contents of the variable DIALSTATUS with the value of BUSY.

Here is the whole of line 2 for you to look at again.
exten => 207,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)

If DIALSTATUS is equal to BUSY we are going to go to the TrueDestination (busy) but is it is not equal to BUSY we are going to go to the FalseDestination (unavail).

You can see that (busy) is on the 5th line of our exten 207 dialplan.
exten => 207,n(busy),Voicemail(207@default,b)

So if line 2 is true we jump down to line 5 and we call the Voicemail application and request the busy greeting message.

On the other hand if line 2 is false we jump down to line 3.
exten => 207,n(unavail),Voicemail(207@default,u)

This is where you see the label (unavail) and call the Voicemail application and request the unavailable message.

Great so now Asterisk is able to decide which Voicemail message to play based on whether or not we are on the phone. That is great but I don’t want to have to type all those lines for each extension. That is where macros come in.

Macros are special contexts sections of the extensions.conf file. You start a macro context with the word macro followed by a dash (-) and the name of the macro. So our voicemail macro might start like this:
[macro-voicemail]

The s extension is the only one you can have in the a macro section.

To call a macro you use the Macro() application like this:
[internal]
exten => 207,1,Macro(voicemail,207)

So I replaced 6 lines with one single line that is calling my Macro named “voicemail” and passing it a variable which is my phone extension number “207”.

The Macro will look almost the same as the 6 lines I replaced.

[macro-voicemail]
exten => s,1,Dial(SIP/${ARG1},10)
exten => s,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => s,n(unavail),VoiceMail(${MACRO_EXTEN}@default,u)
exten => s,n,Hangup()
exten => s,n(busy),VoiceMail(${MACRO_EXTEN}@default,b)
exten => s,n,Hangup()

Here:
exten=>207 was replaced with the exten=>s (only s is allowed in a macro)
SIP/207 was replaced with SIP/${ARG1}, (ARG1 is the extension number passed to the macro)
207@default was replaced with ${MACRO_EXTEN}@default (Extension the macro was called from)

ARG1 and MACRO_EXTEN hold the same data so I really don't need both, but you can see that there are two ways to get the extension. One way is to pass it into the macro or else use the MACRO_EXTEN. MACRO_EXTEN is automatically loaded by Asterisk with the value of the extension that called the macro.

So with this macro I only need to add one line to the extensions.conf file. So I might add 3 phones under context [internal] like this:
exten => 207,1,Macro(voicemail,207)
exten=> 208,1,Macro(voicemail,208)
exten=> 209,1,Macro(voicemail,209)

To get the messsage waiting light to work you need to add a line to the sip.conf file.
Mailbox=207
If I had used a different voicmail.conf context, other then default, I would have to specify the context like:
mailbox=207@WhatEverTheContextName

Now we need to go to the asterisk console and run the command:
> reload (that will load the voicemail.conf changes as well as the other changes we made)

Should be able to call the extension and leave a voicemail message now.

Back in post 5 we configured the cisco sip dialplan to dial 500. We also configured the SIPDefault.cnf file to assign this number to the message button on the cisco phones.

This is what I am going to setup as now as the number to check voicemail.
In the extensions.conf file:

exten => 500,1,VoiceMailMain(${CALLERID(num)}@default)

500 will now dial voicemail. The CALLERID(num) will match the number I am calling from so that I do not manually have to enter the mailbox number. I will just be prompted for the password.

Next time call parking and MeetMe conference Calls

Asterisk PBX System Install - 10 Conference And Parked Calls

Asterisk PBX Install - Index

No comments: