Asterisk For a Small Business (V)

By | 2012-09-02

Last time we had reached a milestone. Internal calls working, outbound calls working, and incoming calls working.

What next then? It would be nice if people calling our business or residential line got an answering machine when we weren’t in wouldn’t it?

There are two dialplan functions needed for voicemail:

  • Voicemail() which connects a caller to the recording service – lets them leave a message.
  • VoicemailMain() which connects a caller to the listening service – lets them listen to their recorded messages.

We’ll begin with a slightly unrelated reorganisation. Recall that we did this to handle external calls:

[external]
exten => voiptalkRESIDENTIAL,1,Verbose(1,Incoming call on callbackextension=${EXTEN})
exten => voiptalkRESIDENTIAL,n,Dial(SIP/andyp&SIP/wife&SIP/handytone1)
exten => voiptalkOFFICE,1,Verbose(1,Incoming call on callbackextension=${EXTEN} from ${CALLERID(all)})
exten => voiptalkOFFICE,n,Dial(SIP/andyp&SIP/handytone2)

That is to say we used Dial(). Instead, let’s make the system slightly more flexible by using Asterisk’s queue system.

Edit the /etc/asterisk/queues.conf file and add a queue for each of our endpoint groups.

[residential]
strategy = ringall    
member => SIP/andyp
member => SIP/wife
member => SIP/handytone1

[business]
strategy = ringall    
member => SIP/andyp
member => SIP/handytone2

Then we’ll alter the [external] context to use queue dial.

[external]
exten => voiptalkRESIDENTIAL,1,Verbose(1,Incoming call on callbackextension=${EXTEN})
exten => voiptalkRESIDENTIAL,n,Queue(residential,cnrtk,,,30)
exten => voiptalkOFFICE,1,Verbose(1,Incoming call on callbackextension=${EXTEN} from ${CALLERID(all)})
exten => voiptalkOFFICE,n,Queue(business,cnrtk,,,30)

This method gives us more flexibility in how we handle queue members coming and going (see the Asterisk documentation for the definitions of the ‘cnrtk’ flags).

Now we add fallback to the voicemail if no one answers:

[external]
exten => voiptalkRESIDENTIAL,1,Verbose(1,Incoming call on callbackextension=${EXTEN})
exten => voiptalkRESIDENTIAL,n,Queue(residential,cnrtk,,,30)
exten => voiptalkRESIDENTIAL,n,Voicemail(household)
exten => voiptalkOFFICE,1,Verbose(1,Incoming call on callbackextension=${EXTEN} from ${CALLERID(all)})
exten => voiptalkOFFICE,n,Queue(business,cnrtk,,,30)
exten => voiptalkOFFICE,n,Voicemail(business)

This isn’t quite sufficient. We have to tell Asterisk the names of the voicemail boxes. Edit /etc/asterisk/voicemail.conf.

[default]
andyp       => IGNOREPASSWORD,Andy Parkins,andyp@localhost
wife        => IGNOREPASSWORD,wife,wife@localhost
household   => IGNOREPASSWORD,Residence Voicemail
business    => IGNOREPASSWORD,Business Voicemail,business-voicemail@localhost

Leaving the andyp and wife voicemail boxes aside for a moment, we’ve established a way of leaving messages, but how do we pick them up? First we need to decide what we’d like.

  • Dialling the special extension 1571 from handytone1 gets you to the residential voicemail. (1571 is the BT number for their voicemail service, people already know it so why not leverage that?)
  • Dialling the special extension 1571 from handytone2 gets you to the business voicemail.

We’re seasoned users of the dialplan now. This is very straightforward.

[internal-residential]
include => internal-extensions
exten => 1571,1,VoicemailMain(household,s)
exten => _0X.,1,Dial(SIP/voiptalkRESIDENTIAL/${EXTEN})

[internal-business]    
include => internal-extensions
exten => 1571,1,VoicemailMain(business,s)
exten => _0X.,1,Dial(SIP/voiptalkOFFICE/${EXTEN})

We’ve simply added the same extension to two contexts, but with different commands when it matches. The ’s’ flag to VoicemailMain() means don’t ask for a passcode; we don’t need a passcode as we’re using the context to establish security. Can we do better though? Yes. Scrap the previous. Recall one of our local extension endpoint definitions.

[handytone1](user,ht386)
    secret=handytonesecret1
    callerid="Residential" <2102>
    context=internal-residential
    mailbox=household@default

The mailbox option also lets us write code that accesses a different mailbox depending on who dialled a common access number. Add the following:

[internal-extensions]
; Numeric aliases
exten => 2100,1,Goto(andyp,1)
exten => 2101,1,Goto(wife,1)
exten => 2102,1,Goto(handytone1,1)
exten => 2103,1,Goto(handytone2,1)
exten => 1571,1,Goto(voicemail,1)
; Named extensions
exten => andyp,1,Gosub(stdexten,s,1(SIP/${EXTEN},${EXTEN}))
exten => andyp,hint,SIP/${EXTEN}
exten => wife,1,Gosub(stdexten,s,1(SIP/${EXTEN},${EXTEN}))
exten => wife,hint,SIP/${EXTEN}
exten => handytone1,1,Gosub(stdexten,s,1(SIP/${EXTEN},${EXTEN}))
exten => handytone1,hint,SIP/${EXTEN}
exten => handytone2,1,Gosub(stdexten,s,1(SIP/${EXTEN},${EXTEN}))
exten => handytone2,hint,SIP/${EXTEN}
; Special extensions
exten => voicemail,1,Ringing
exten => voicemail,n,Set(mailbox=${SIPPEER(${CHANNEL(peername)},mailbox)})
exten => voicemail,n,GotoIf($["${mailbox}" = ""]?end)
exten => voicemail,n(message),Verbose(1,Transferring ${CALLERID(all)} to ${mailbox} voicemail)
exten => voicemail,n,SendText(Connected to ${mailbox} Voicemail)
exten => voicemail,n,Wait(2)
exten => voicemail,n,Answer
exten => voicemail,n,VoicemailMain(${mailbox},s)
exten => voicemail,n(end),Hangup

This additional named extension, voicemail, doesn’t direct the caller to an endpoint, instead it checks to see if there was an mailbox set in sip.conf (or any other endpoint device defintion file), then runs VoicemailMain() with a mailbox of that name.

The advantage here is that we can specify the voicemail box independently of device name or context. We could now easily point andyp at either the andyp mailbox or the business mailbox, and similarly for any other extensions we add.

One final note, the mailbox option in the endpoint definition primarily tells the phone its default mailbox (should it support that facility) to subscribe to for its message waiting indicator (i.e. a little light on the phone that tells you whether you have new voicemail). The vmexten option in the user template lets us tell the phone what extension to dial in response to a push of its voicemail button (should it support that facility) – this would save the user even having to know 1571.

asterisk1 asterisk2 asterisk3 asterisk4 asterisk5

Leave a Reply