VOIP Routing for Non-US, 10-Digit NANPA Numbers in Asterisk

I got my AT&T bill this morning with $150 in long distance charges for calls to Canada. After cursing AT&T under my breath I resolved not to let this happen again.  Knowing AT&T charges exorbitant rates for international calls ($1.39/minute to Canada? Really?) I have international calls set to route through a VOIP provider where I pay 1.39 CENTS to call Canada and the rest of the developed world.  As soon as you hit 011 on our phone system you’re automatically routed to VOIP.  The problem is, thanks to NANPA, Canadian phone numbers, and some islands in the Caribbean, look just like US numbers, 1-XXX-XXX-XXXX, but charge like you’re calling Iran.  What to do?

There doesn’t seem to be any easy way to detect an international number within NANPA other than to make a list of the international area codes, so that’s what I did.  Based on this and this I wrote a quick snippet of Ruby code to generate my dialplan rules:

# Canada
codes = %w{204 250 289 306 403 416 418 450 506 514 519 604 613 647 705 709 778 780 807 819 867 902 905}
# Islands
codes += %w{809 441 787 939 340 670 671 684 599 721}
codes.each {|code| puts "exten = _#{code}XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})\nexten = _1#{code}XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})"};

I have my phone system set up to let me dial 10 digit numbers either with or without the initial 1, so there are two entries for each area code.  Here’s the result.

exten = _204XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1204XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _250XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1250XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _289XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1289XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _306XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1306XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _403XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1403XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _416XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1416XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _418XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1418XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _450XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1450XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _506XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1506XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _514XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1514XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _519XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1519XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _604XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1604XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _613XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1613XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _647XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1647XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _705XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1705XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _709XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1709XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _778XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1778XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _780XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1780XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _807XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1807XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _819XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1819XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _867XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1867XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _902XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1902XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _905XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1905XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _809XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1809XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _441XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1441XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _787XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1787XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _939XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1939XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _340XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1340XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _670XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1670XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _671XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1671XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _684XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1684XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _599XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1599XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})
exten = _721XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN})
exten = _1721XXXXXXX,1,Macro(trunkdial,${Vitelity}/${EXTEN:1})

Now my calls to Canada and the islands go through the VOIP provider Vitelity, where I pay 1/100 as much as I did with AT&T.  Decent savings for adding a few entries to extensions.conf.

 

This entry was posted in Personal. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *