Networking

SolutionBase: Configuring additional features <br>in Asterisk 1.2

If all Asterisk did as a VoIP solution was route calls, it would get the job done, but not be a very good alternative to proprietary systems. In this article, Brian Smith shows how to modify <i>.conf</i> files in Asterisk 1.2 to customize call handling.

One of the advantages of using Asterisk as a VoIP solution for your organization is that it's as flexible as it is powerful. Once you get it up and running, there are many different options you can tweak and modify to make Asterisk do exactly what you want. In this article, I'm going to show you how you can utilize some of the additional features that come packaged with Asterisk. By the end of this article, you'll have set up your dial plan to emulate common menu features, including a simple call center and call logging.

Author's note

At the time of writing, the current stable release of Asterisk is 1.2; 1.4 is available as a beta release. All the details of this article should be the same for both releases.

Creating menus for extensions

Let's begin by covering how to create a menu using a series of extensions. To do this, first you'll want to create a new context and a series of extension instructions. Below is an example of a very simple menu to give the person on the phone a list of options to connect them with a department leader. The syntax of this menu follows that of a normal extension group, with the context and then a list of extensions each with priorities and instructions.

[mainMenu]
include => default
exten => s,1,Ringing
exten => s,n,SetMusicOnHold(default)
exten => s,n,DigitTimeout,5
exten => s,n,ResponseTimeout,10
exten => s,n(intro),Background(announce-options)
exten => s,n,WaitExten
exten => s,n,Goto(intro)
; Sales Department
exten => 1,1,DialExten(212,SIP/212)
exten => 1,n,Hangup
; Billing
exten => 2,1,DialExten(313,SIP/313)
exten => 2,1,Hangup
; Customer Service
exten => 3,1,DialExten(404,SIP/404)
exten => 3,n,Hangup
; Invalid Extension Dialed
exten => i,1,Answer
exten => i,n,Playback(invalid-extension)
exten => i,n,Goto(intro)

An interesting aspect to extensions is that you can make them perform a function or a series of functions. To initiate the process, you can have an external connection through a Zaptel or SIP connection forward to the mainMenu context by using the Goto command. This can be done in the extensions.conf file using your favorite text editor.

Here is an example of how to forward a call from your external connection (i.e., a PRI line or IAX / SIP account) to this new menu. In this example, the external connection is the remote context:

[remote]
exten => _555XXXX,1,Goto(mainMenu,s,1)

Remember, your incoming DID number is still an extension, and it's quite common that if you have a PRI line, you probably have a block of DID's. Given that assumption, your dial plan will need to be able to state simply that any phone call being received from any extension (in this case incoming calls) should be forward to the menu at context mainMenu.

Remember the wildcard extensions begin with the underscore at the beginning of the extension definition and are coded like a regular expression. The easiest way to use this is the variable replacement of individual digits using the N, X, and V code. 'X' meaning any number between 0 and 9 with Z being any number between 1 and 9 and N is between 2 and 9.

Now that you have an extension forwarding to your new mainMenu context, you'll want to have an automated announcement answer the phone. This message can be a prerecorded MP3 file that states something along the line of "Thank you for calling, for sales please dial 1, for billing please dial 2, and for customer service please dial 3."

This behavior occurs because of the line that states exten => s,n(intro),Background(announce-options). This creates a sort of place holder by defining intro within the parentheses. The place holder only exists within the context it's defined in, and its behavior is exemplified when an invalid extension is dialed in the menu. What will happen is Asterisk will answer the line, and playback a message that informs the user that they have dialed an invalid extension. After the message is finished playing the user is forwarded back to the intro message so that the user can be presented with the dialing options again.

Note the command include which instructs Asterisk to include the 'default' context into the current mainMenu context. This allows the user to be able to dial a direct extension to anyone inside your default context further exemplifying the division of contexts in Asterisk.

Additionally, a nice touch is to set some hold music. Hold music is a standard feature of any PBX system, and Asterisk naturally supports such a basic feature. It's very simple to set default hold music. Hold music is defined in the same context type of definitions in the musiconhold.conf file. You can also allow users to define their own hold music for their individual extension.

Conference rooms

Another great function that Asterisk deploys with is the support for conference rooms. Much like the actual physical spaces in an office, conference rooms are the places that people collaborate on ideas and projects, brain storm and deals are made. You've probably used a phone based conference room that was probably run by a proprietary and very expensive commercial PBX solution.

To start creating an Asterisk-based phone conference room, open up the meetme.conf file located in the Asterisk configuration directory — typically located at /etc/asterisk — with your favorite text editor. Then follow this syntax conf => conference-room-number,pin,admin-pin add conf => 8000 under the [rooms] section of the file.

This will define a new conference room with the ID 8000. Please note that in order for the MeetMe application to work, you'll need the Zaptel module loaded, with at least the ztdummy module loaded into the kernel.

You'll then need to modify your dial plan to connect an extension to your conference room that will allow users to join in. To do this, edit your extensions.conf file with your text editor again and add the following lines:

[conferenceRooms]
exten => 333,1,Answer
exten => 333,n,MeetMe(8000|ciM)
exten => 333,n,Playback(vm-goodbye)
exten => 333,n,Hangup

Then, in any context you would like to have users be able to join a conference room (such as your office), just add the line include => conferenceRooms in order to include the conferenceRooms context to your local context. In the previous example, I made the extension that would be dialed forward using a Goto statement, 333. The first instruction is to answer and pick up the line and then enter them into the MeetMe application (conference room).

If you look closely at the listing, you'll see that the options that were passed to the MeetMe command were c, i, and M, indicated by the one word ciM. There are many options available and these are just three. These options announce the user when someone enters or leaves the conference room. A voice will state that "John Doe has left the conference room". The c and i options do this. Option M tells Asterisk if there is only one user in the conference and will play hold music until others join.

At any time any user in the conference room can dial [*] to enter a menu. User menus and administrative menus are both available. The pin number entered by the caller when they join the conference call determines which menu they can access.

Call queues (call centers)

Now we're into a whole new realm with Asterisk; you are no longer content with talking to each other, now dozens of people need to talk to you. You need to setup a solution that can scale to meet this demand while still getting the phones answered.

First you'll need to open the queues.conf file with your text editor and add a section like this:

[sales_queue]
music => default
strategy => ringall
context => office
timeout => 15
announce-frequency => 30
announce-holdtime => yes
joinempty => yes
member => SIP/212
member => SIP/213

This is an example queue that has been created for the sales department. It uses the default hold music and is in the context office. If a user decides while waiting in the queue that they would prefer to speak to a person directly and know the extension to dial they can do so without having to wait further. Also notice the announce-frequency and announce-holdtime parameters. These tell Asterisk to announce to the caller their position in the queue, and to do so every 30 seconds.

The joinempty option simply indicates that if no members are accessible and the queue is empty, callers are not allowed to go into the queue.

The member parameter adds additional extensions the queue should contact. These members can be SIP connections or Zaptel connections.

There are multiple methods for ringing the members in this example It's ringall, and simply means that all members should be rang at the same time. Other ring types include:

  • fewestcalls: Rings the interface with the fewest completed calls in the queue being referenced
  • leastrecent: Rings the interface which has been the least recently contacted by the queue
  • random: Makes a random selection
  • ringall: The default behavior of Asterisk rings all available interfaces until one answers
  • roundrobin: Takes turns ringing each interface
  • rrmemory: Round robin will pick up with the last phone rang from the previous ring

After you have defined the queue to exist, you need to modify the menu you created before to forward the caller into the queue. So open up extensions.conf again with your favorite text editor and let's re-examine the old sales line.

; Sales Department
exten => 1,1,DialExten(212,SIP/212)
exten => 1,n,Hangup

Assume after weeks of being bombarded by sales calls, Bob needs a little assistance, but the menu needs to remain the same. Here's what to replace this with.

; Sales Department
exten => 1,1,Playback(announce_caller_about_to_enter_queue)
exten => 1,n,Queue(sales_queue|tT)
exten => 1,n,Playback(announce_thank_you_for_calling)
exten => 1,n,Hangup

I threw in a little semantics to play announcements to the caller — they "are about to enter the sales queue and your call should be answered in the order in which it was received" — and a final goodbye message after the caller disconnects from the Queue Agent (Bob or his assistant).

Forwarding a call into a queue is performed by using the Queue command. In this example, I wanted to pass the two options — tTthat allowed the caller and called agent to be able to forward the call to another extension.

Putting it all together

Now that you've learned how to create your own menus and the basics of how to setup a call center, let's put it all together. In the normal flow of events, you'll receive a phone call from your PRI (Zapata) interface, from DID 555-5555. This caller could be calling in for any reason, so you'll to present them with a few options, like how to contact support, the sales team, or billing, without having to already know the direct extensions to their intended target. The only caveat is that if your sales force is overloaded by the number of calls, business is good.

In such a situation, you may want to at least split the load for answering sales between two people, Bob at extension 212 and Joe at extension 213. So let's revisit and modify the menu that I presented before for new incoming calls and modify it for these new changes.

Open up queues.conf file with your text editor. The changes you want to make include creating the definition for a new call queue that has hold music, rings both Bob and Joe at the same time, and still allow the caller to dial Bob directly thus leaving the queue. The changes you'll make to the queues.conf file to do this would be:

[sales_queue]
music => default
strategy => ringall
context => office
timeout => 15
announce-frequency => 30
announce-holdtime => yes
joinempty => yes
member => SIP/212
member => SIP/213

After you have configured the queue to exit, you'll need to modify your dial plan to have an entry menu that presents the user with a series of options. This is pretty easy, because all you have to do is borrow from the previous menu example, but modify it to forward the caller into the queue during when selecting to call sales. Notice that the remote context is assumed to be the same context as your Zapata interface, so these callers should be your remote callers from the Public switched telephone network (PSTN) aka the outside world. The changes you'll make will look like:

[remote]
exten => _555XXXX,1,Goto(main_menu,s,1)
  [main_menu]
include => default
exten => s,1,Ringing
exten => s,n,SetMusicOnHold(default)
exten => s,n,DigitTimeout,5
exten => s,n,ResponseTimeout,10
exten => s,n(intro),Background(announce-options)
exten => s,n,WaitExten
exten => s,n,Goto(intro)
; Sales Department
exten => 1,1,Playback(announce_caller_about_to_enter_queue)
exten => 1,n,Queue(sales_queue|tT)
exten => 1,n,Playback(announce_thank_you_for_calling)
exten => 1,n,Hangup
; Billing
exten => 2,1,DialExten(313,SIP/313)
exten => 2,1,Hangup
; Customer Service
exten => 3,1,DialExten(404,SIP/404)
exten => 3,n,Hangup
; Invalid Extension Dialed
exten => i,1,Answer
exten => i,n,Playback(invalid-extension)
exten => i,n,Goto(intro)

More than just a phone system

Asterisk has many features ready for deployment that normally would only be available on extremely expensive closed solutions. I hope this article has given you the confidence to move forward with deploying these features yourself. Asterisk offers a robust feature-set of pre-built technologies, as well as the framework to make VoIP do anything you want it to.

Editor's Picks

Free Newsletters, In your Inbox