snork.ca ... making kittens cry since 2001
homeabouttoscanaryrssmansvalidatecontactsearch

Asterisk Inbound And Outbound Calling 2013-12-27


Outbound

So here's how I have my phones setup at home... I have a phone line from voip.ms that costs $1 a month for the number, and a half cent per minute as I talk on it. Then I have a phone line from freephoneline.ca that cost $50 to get, has unlimited inbound calling for free, and is limited to certain Canadian cities for outbound calls (which are also free). So when I call out I of course want to normally use my freephoneline.ca number because it costs me nothing. However, if the place I am calling is not on the magic list of Canadian cities then I want to use my voip.ms line. I also thought it might be nice to set it up so that if I only dial seven digits it will assume to use my local area code and will add it in for me. Now, I like to think that I have some "computer goof" knowledge, but programming (or development as the snobs like to say) is not something I enjoy. Having said that, setting up a couple of outbound trunks in Asterisk wasn't a big deal... my extensions.conf has something like this:

; Outbound rules for fpl trunk
exten => _NXXXXXX,1,Dial(SIP/666${EXTEN}@fpl-trunk)
exten => _NXXNXXXXXX,1,Dial(SIP/${EXTEN}@fpl-trunk)
; Outbound rules for vms trunk
exten => _9NXXXXXX,1,Dial(SIP/666${EXTEN:1}@vms-trunk)
exten => _9NXXNXXXXXX,1,Dial(SIP/${EXTEN:1}@vms-trunk)

The first line takes any seven digit number dialed, adds my area code (666) at the front, and dials it through my freephoneline trunk. The second line takes any ten digit number dialed and dials it as is via freephoneline. The next pair of lines does the same thing for voip.ms but only if the number starts with a 9 (of course it strips the 9 before dialing the number).

Of course all this requires that I have properly setup fpl-trunk and vms-trunk in my sip.conf and that I am able to properly register with them. This setup also does not account for numerous different kinds of international numbers that can have a wide range of formats. The end result is that when I want to call someone, I just dial the 7 digit number... if they are in a different area code I just make it 10 digits... if they are not in freephoneline's list of approved numbers I dial a 9 first, and go through my paid (though cheap) trunk provider.

Inbound

Okay, so outbound calling wasn't so hard... inbound needed a bit more thought. One thought is that I really don't like telemarketing, especially war dialers. Since neither of my phone numbers are published anywhere I have to assume that almost all telemarketers got my number by war dialing (the rest were sold my number by unscrupulous businesses posing as legitimate who asked for my number). I decided to make a flowchart showing how my calls should be handled.

call-flow Flow diagram

With my call flow defined I could now create a dialplan that would follow it. At first I didn't bother to apply this to the voip.ms number but I quickly changed my mind and did it there too. Let's see if I can present this in a readable form... here is the initial section that takes in the calls from freephoneline.ca:

[from-fpl-trunk]
; Let's check to see if you are blacklisted first
exten => 16133663349,1,GotoIf(${BLACKLIST()}?you-are-blacklisted,s,1)
; Now let's see if you are whitelisted
exten => 16133663349,2,GotoIf(${DB_EXISTS(whitelist/${CALLERID(num)})}?you-are-whitelisted,s,1)
; Remaining calls are on neither black nor white list
exten => 16133664449,3,Goto(you-are-unknown,s,1)
; If your call made it this far, something fucked up
exten => 16133664449,4,Playback(something-went-wrong)
exten => 16133664449,5,Wait(2)
exten => 16133664449,6,Hangup()

Asterisk has a database that you can modify... if you type this at the Asterisk CLI

database put BLACKLIST 6661112222 "Annoying caller from Hell"

it will add the phone number as a record in the database. The BLACKLIST() function in the first line there checks to see if you are in the database (specifically in the family called blacklist) – and if you are, it sends you to the section called you-are-blacklisted. The section for blacklisted numbers is pretty simple and just does this:

[you-are-blacklisted]
; Play donkey and hang up
exten => s,1,Answer(3000)
exten => s,n,Playback(donkey)
exten => s,n,Wait(1)
exten => s,n,Hangup()

Answer the call, wait a few seconds, play "The Donkey Noise", wait an additional second, then hang up. If you need to remove a number from the blacklist use this:

database del 6661112222

And if you want to view the database you can use:

database show blacklist

Okay, so the next line is essentially the same as the blacklist line except it checks for whitelisted numbers. There is no built-in function for whitelisting so the syntax is a little different but modification of the database is done the same way. The downside of using a whitelist is that you'll want to populate the whitelist with people you know or they'll have to press 4 to talk to you. Here's what happens to people in the whitelist:

[you-are-whitelisted]
; Check time, ring phones or go to VM
exten => s,1,GotoIfTime(08:00-22:00,*,*,*?ring-the-phones,s,1)
; It's too late, just drop to voicemail
exten => s,n,Answer(3)
exten => s,n,VoiceMail(201,u)
exten => s,n,Hangup()

The first line checks the time, if it is between 8am and 10pm it sends the caller off to a section called ring-the-phones and if it is not between those times, it just drops them to voicemail (the u at the end of the voicemail line tells it not to play the default Asterisk prompt after playing your personal greeting). The third line in the answer sequence should cover everyone else (numbers that are not whitelisted and not blacklisted). There is a check afterwards that basically would pickup anyone who mistakenly get past the first three (which nobody should). Anyways, the unknown callers go to a section called you-are-unknown which looks like this:

[you-are-unknown]
; Check time, ask if human or go to VM
exten => s,1,GotoIfTime(08:00-22:00,*,*,*?are-you-human,s,1)
; It's too late, just drop to voicemail
exten => s,n,Answer(3)
exten => s,n,VoiceMail(201,u)
exten => s,n,Hangup()

The first thing this does is check the time, if they are calling after 10pm then I don't care who they are, they just drop to voicemail. However, if they are calling during the day then I send them to a section called are-you-human to confirm that they are a person which looks like this:

[are-you-human]
; Ask if caller is a person (press 9)
exten => s,1,Answer(3)
exten => s,n,Set(TIMEOUT(digit)=2)
exten => s,n,Set(TIMEOUT(response)=8)
exten => s,n,Wait(1)
exten => s,n,Background(unknown-number)
exten => s,n,Background(silence/5)
exten => s,n,Background(unknown-number)
exten => s,n,Background(silence/5)
exten => s,n,Background(unknown-number)
exten => s,n,Background(silence/5)
exten => s,n,Playback(sorry-having-trouble)
exten => s,n,Hangup()

This basically gives them a few chances to press 4 by using the Background() function which plays a sound file and lets them press a digit. The first few lines are for setting up the options for their timeouts when pressing numbers. The rest of this section looks like this:

exten => 4,1,Playback(thank-you)
exten => 4,n,Goto(ring-the-phones,s,1)
exten => 4,n,Hangup()
exten => i,1,Playback(sorry-having-trouble)
exten => i,n,Hangup()
exten => t,1,Goto(are-you-human,s,1)

The idea here is to dump the caller if they can't press 4 to talk to me, the i extension is "invalid" and t is "timeout". Telemarketers and scammers often use what is called a war dialer which is given a range of phone numbers and is sent off to dial them. If the war dialer gets an answer from you, it plays a message saying "You have won a billion dollars, press 1 to claim your prize!"... if you press 1 then you are transferred to a human who is waiting for another sucker. This allows the telemarketers to hire only a few humans and also reach more phone numbers (because the war dialer doesn't take bathroom breaks). The good news is that the war dialers probably won't press 4 and will get hung up on. If all goes well for the caller they eventually drop in to this section which actually makes my phones ring:

[ring-the-phones]
; It must be daytime
exten => s,1,Answer()
exten => s,n,Dial(SIP/201&SIP/202,18)
exten => s,n,Voicemail(201,u)
exten => s,n,Hangup()

This basically makes both of my phones ring for 18 seconds and drops to voicemail if I don't answer. The last section is actually a little different now because I have added call forwarding, but that'll have to be another post.

Made using Notepad++ & FastStone, hosted using nginx & php, search by JRank, and powered by North Korean mushrooms.