*** PART #1 of 2***
************************
Hi There,
ever since I discovered sipsorcery ... I love the things I can do.
Here is a dialplan I want to share and hope that others can use it too or at least get inspired by it.
Robert
PS: Just make sure you do NOT use the Silverlight interface, when putting it in ... the plan is just too BIG
Have Fun:
### I had to SPLIT the post into TWO parts, because ... its bigger than the max allowed
Code: Select all
#Ruby
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
# #
# ATTENTION #
# #
# This dial plan is TOO BIG / LONG #
# #
# ===> You can ONLY enter / edit it in the "normal" web interface. #
# #
# it does NOT WORK with the SILVERLIGHT interface #
# #
# This has NOTHING to do with the execution / performance its just "cosmetics" #
# #
###############################################################################################################
###############################################################################################################
###############################################################################################################
# Copyright 2011 - 2014 Robert Nio
# Copyright 2010 Mike Telis, Mike Green, and Steven Jackson
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# Script is based on a script originally posted by Mike Telis
###############################################################################################################
###############################################################################################################
###############################################################################################################
# FEATURES of this dialplan:
#
# Support making your ATA device a little more intelligent
# Support for E911 (link of VOIP number to physical address for emergency calls)
# Support for commercial and free CNAM service providers (match number to name)
# Support for PERSONAL CNAM directory (match numbers to names e.g. 123-4444 ==> Daddy)
# Support for PERSONAL ENUM database (ability to call extensions INTERNALY rather than to route the call through an outside sip-provider)
# Support to set custom Caller ID (PROVIDER must support this ... DIDLOGIC does)
# Support for RULES based on time in coming CLI etc.
# Support SIMPLE and COMPLEX speeddial numbers
# Support "E164" dialing format
# Support for various international prefixes (e.g. 00 | 011)
# Support various SIP-PROVIDERS incl. Google Voice
# Support for MANUAL & AUTOMATIC SIP-Provider selection (e.g. international call to provider A ... domestic calls to provider B)
# Support for Google Voice as a VOIP provider (dial-out)
# Support for simple Google Voicemail retrieval
# Support Call-Trunks (ability to call multiple lines simultaneously)
# Support for customize actions depending who is calling (e.g. forward to specific number when daddy calls)
# Support of misdialing safeguards (e.g. avoid expensive premium calls by accident)
# Support restricting the countries one can call
# Simplified LOGGING / DEBUGGING of your dialplan
# Provides extensive logging during dialplan execution
# Makes use of NICE number formatter from mike :)
#
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
#
# We did INCULDE "mikesgem" in this script, because we needed to EXTEND the VSP definition with "intPrefix"
#
#require 'mikesgem'
#
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
class Hash; alias :+ :merge; end; Home,Mobile,Work,Gizmo = 1,2,3,7
# **** My classes. DO NOT EDIT from here ********************************* #
class VSP
@vsptab = {}
def self.tab; @vsptab; end
attr_reader :fmt, :name, :repeat, :tmo, :intPrefix
def initialize *args
attrib = args.pop
args << attrib and attrib = {} unless attrib.class == Hash
@pfx, @fmt, @name = args
attrib.empty? || %w{pfx name tmo intPrefix fmt repeat rand}.each do |attr|
ivar = "@#{attr}"; val = attrib.delete(attr.to_sym)
instance_variable_set(ivar,val) if val && !instance_variable_get(ivar)
end
@repeat ||= 1; @fmt ||= '+${EXTEN}' if is_gv?
unless @pfx.to_s.empty?
raise "Duplicated dial prefix '#{@pfx}'" if VSP.tab.has_key?(@pfx)
VSP.tab[@pfx] = self
end
@attrib = attrib if is_gv?
end
def is_gv?; self.class == GV; end
end
class GV < VSP
attr_reader :rand
def getparams num, i=0
acnt = @attrib[:account] || Array[@attrib]
a = {:num => num, :tmo => @tmo || 10, :match => '.*'} # init with default values
a.update(acnt[i % acnt.length]) # add other params
a[:cb].gsub!(/\D/,'') # Delete all but digits
a[:type] ||= (a[:cb] =~ /^1?111/) ? Gizmo : Home # if no type, define it depending on area code "111"
a.values_at(:usr, :pwd, :cb, :num, :match, :type, :tmo)
end
end
def Provider(*args)
a = args.last; a.class == Hash && (a[:usr] || a[:account]) ? GV.new(*args) : VSP.new(*args)
end
# **** .......................... to here ******************************** #
# ************************* f o r m a t N u m ****************************
def formatNum(num,exact=false)
case num
# Closed Numbering Plan
when /^(39)(0[26]|0\d[0159]|0\d{3}|3\d\d)(\d*)(\d{4})$/, # Italy: Milan, Rome, 0x0, 0x1, 0x5, 0x9, 4-digit
/^(41|48)(\d{2})(\d{3})(\d{4})$/, # Swiss, Poland
/^(34)(9[1-9]|[5-9]\d\d)(\d{3})(\d{3,4})$/, # Spain
/^(32)(4[789]\d|[89]0\d|[2-4]|[15-8]\d)(\d{3})(\d{3,4})$/, # Belgium
/^(86)(1[2-9]\d)(\d{3,4})(\d{4})$/, # China mobile
/^(886)(37|49|89|\d)(\d*)(\d{4})$/, # Taiwan
/^(972)(\d{1,2})(\d{3})(\d{4})$/, # Israel
/^(31)(6|800|8\d|9\d\d)(\d*)(\d{4})$/ # Netherlands non-geo
sep = $3[2] ? '-' : '' # separator if $3 group has 3 or more digits
"+#$1 #$2 #$3#{sep}#$4"
# Open Numbering Plan
when /^([17]|90)(\d{3})(\d{3})(\d{4})$/, # USA, Russia, Turkey
/^(61)(\d)(\d{4})(\d{4})/, # Australia
/^(49)(1[5-7]\d|30|40|69|89|\d\d1|\d{4})(\d*)(\d{4})$/, # Germany: (mobile|2dig|3dig|4dig) area
/^(380|375|998)(\d{2})(\d{3})(\d{4})$/, # Ukraine, Belarus, Uzbekistan
/^(370)(469|528|37|45|46|57|5|\d{3})(\d*)(\d{4})$/, # Lithuania
/^(36)(1|\d\d)(\d{3})(\d{3,4})$/, # Hungary
/^(86)(10|2\d|\d{3})(\d{3,4})(\d{4})$/, # China: Beijing, 2x, others 3-dig area code
/^(91)(800|11|20|33|40|44|[789]\d|\d{3})(\d*)(\d{4})$/, # India
/^(63)(2|[3-8]\d|9\d\d)(\d{3})(\d{4})$/, # Philippines (Manila, [3-8]x, 9xx - mobile)
/^(81)(3|6|[2-9]0|\d\d0|\d\d)(\d*)(\d{4})$/, # Japan
/^(55)(\d\d)(\d{4})(\d{4})$/, # Brazil
/^(31)(7\d|[1-5][035]|2[46]|3[68]|46|58|\d{3})(\d*)(\d{4})$/ # Netherlands geo
sep = $3[2] ? '-' : '' # separator if $3 group has 3 or more digits
"+#$1 (#$2) #$3#{sep}#$4"
when /^(52)(1)?(33|55|81|\d{3})(\d*)(\d{4})$/ # Mexico
"+#$1#{$2.nil? ? '' : ' ' + $2} #$3 #$4-#$5"
when /^(33)(\d)(\d{2})(\d{2})(\d{2})(\d{2})$/ # France
"+#$1 #$2 #$3 #$4 #$5 #$6"
when /^(44)(11\d|1\d1|2\d|[389]\d\d)(\d{3,4})(\d{4})$/, # UK 2- and 3-digit area codes: 11x, 1x1, 2x, 3xx, 8xx, 9xx
/^(44)(\d{4})(\d{3})(\d{3,4})$/ # UK 4-digit area codes
"+#$1 (#$2) #$3 #$4"
when /^(420)(\d{3})(\d{3})(\d{3})$/ # Czech Republic
"+#$1 #$2 #$3 #$4"
when /^(37[12])(\d{3,4})(\d{4})$/ # Latvia, Estonia
"+#$1 #$2-#$3"
when /^(373)([67]\d{2})(\d{2})(\d{3})$/ # Moldova mobile
"+#$1 #$2-#$3-#$4"
when /^(373)(22|\d{3})(\d{1,2})(\d{2})(\d{2})$/ # Moldova landline
"+#$1 (#$2) #$3-#$4-#$5"
when /^(1|2[07]|3[0-469]|4[^2]|5[1-8]|6[0-6]|7|8[1246]|9[0-58]|\d{3})/ # all country codes
exact ? num : "+#$1 #$'" # the pattern used only if exact == false
else num # No match - skip formatting
end
end
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################
#
# Here I kept a copy of my credentials
#
#LP-HOME_NUMBER = "**homenumber**" # my 10-digit Localphone number (Home) EMAIL: myemail@mail.com / ACC#: account_number / PIN: 1234 / SIP-ID: 1234 / SIP-PW: password
#LP-NFB_NUMBER = "**officenumber**" # my 10-digit Localphone number (OFFICE) EMAIL: myemail@mail.com / ACC#: account_number / PIN: 1234 / SIP-ID: 1234 / SIP-PW: password
#LP-EGRB_NUMBER = "**shopnumber**" # my 10-digit Localphone number (SHOP) EMAIL: myemail@mail.com / ACC#: account_number / PIN: 1234 / SIP-ID: 1234 / SIP-PW: password
#SGDE_Nummer = "**germannumber**" # my 10-digit Sipgate number (GERMANY) EMAIL: myemail@mail.com / ACC#: account_number / SIP-ID: 1234 / SIP-PW: password
#
#Google_HOME = "**homenumber**" # my 10-digit Google number (Home) EMAIL: myemail@mail.com / ACC#: myaccount@gmail.com / PW: password
#Google_Office = "**officenumber**" # my 10-digit Google number (OFFICE) EMAIL: myemail@mail.com / ACC#: myaccount@gmail.com / PW: password
#Google_Shop = "**shopnumber**" # my 10-digit Google number (SHOP) EMAIL: myemail@mail.com / ACC#: myaccount@gmail.com / PW: password
#Google_FAX = "**faxnumber**" # my 10-digit Google number (OFFICE-FAX) EMAIL: myemail@mail.com / ACC#: myaccount@gmail.com / PW: password
#
####################################################################
####################################################################
####################################################################
# --------DIAL Plan for your SIP device (phone)--------------------#
####################################################################
####################################################################
####################################################################
#
# The typical CISCO / LINKSYS ATA device is smart enough to help us
# PRE-process the dialed number.
#
# Here is a SAMPLE "Dial-Plan" for your ATA:
#
#
# L:20, The total time we wait ("20" seconds) before we reject the dialing attempt.
# (
# | P9 <:**officenumber**> After taking the phone off hook, a user has "9" seconds to begin dialing. If no digits are pressed we call the DEFAULT # "**officenumber**"
# | x Allow single digit SPEEDDIAL
# | #x**xxS0 This allows to select a Single-Digit-VSP "#x" and then use a SPEEDDIAL "**xx"; do NOT wait for more digits "S0"
# | #xS3 x. This allows to select a Single-Digit-VSP "#x"; we set the wait time between digits to THREE seconds "S3"; followed by the number to dial
# | ##x**xxS0 This allows to select a Single-Digit-Google-Voice VSP "*#x" and then use a SPEEDDIAL "**xx"; do NOT wait for more digits "S0"
# | ##xS3 x. This allows to select a Single-Digit-Google-Voice VSP "*#x"; we set the wait time between digits to THREE seconds "S3"; followed by the number to dial
# | ####**xxS0 Disable Safe Guards "####" and let me dial a SPECIAL SPEEDDIAL
# | ####S3 x. Disable Safe Guards "####" and let me dial whatever I want !
# | #####x**xxS0 Disable Safe Guards "####" and This allows to select a Single-Digit-VSP "#x" and then use a SPEEDDIAL "**xx"; do NOT wait for more digits "S0"
# | #####xS3 x. Disable Safe Guards "####" and This allows to select a Single-Digit-VSP "#x"; we set the wait time between digits to THREE seconds "S3"; followed by the number to dial
# | ######x**xxS0 Disable Safe Guards "####" and This allows to select a Single-Digit-Google-Voice VSP "*#x" and then use a SPEEDDIAL "**xx"; do NOT wait for more digits "S0"
# | ######xS3 x. Disable Safe Guards "####" and This allows to select a Single-Digit-Google-Voice VSP "*#x"; we set the wait time between digits to THREE seconds "S3"; followed by the number to dial
# | **xxS1 SPEEDDIAL Two-Digit "**xx" we set the wait time between digits to ONE second "S1"
# | **xxxS0 SPEEDDIAL Three-Digit "**xxx" with a NO wait time "S0"
# | 1 [2-9]xx [2-9]xxxxxxS0 Recognize a standard us number starting with "1" (3-digit "[2-9]xx" area code and 7-digit number "[2-9]xxxxxx") with a NO wait time "S0"
# | <:1650> [2-9]xxxxxxS2 Accept a 7-digit number "[2-9]xxxxxx" and prepend my local area code "<:1650>" and wait a little between digits "S2"
# | <:1> [2-9]xx[2-9]xxxxxxS0 Accept a 10-digit number "[2-9]xx[2-9]xxxxxx" and prepend "1" to make it an 11-digit US number, and NO wait between digits "S0"
# | 011 x. Allow INTERNATIONAL numbers starting with "011" followed by multiple digits "x."
# | 00 x. Allow INTERNATIONAL numbers starting with "00" (European Style) followed by multiple digits "x."
# | 49 x. Allow GERMAN numbers starting with "49" (dialing format is E164) followed by multiple digits "x."
# | 62 x. Allow INDONESIA numbers starting with "62" (dialing format is E164) followed by multiple digits "x."
# | 972 x. Allow ISRAEL numbers starting with "972" (dialing format is E164) followed by multiple digits "x."
# | 911S0 Call immediately "911" and do NOT wait for more digits
# | 110S0 Call immediately "110" (German POLICE Emergency number) and do NOT wait for more digits
# | 112S0 Call immediately "112" (German FIRE / AMBULANCE Emergency number) and do NOT wait for more digits
# | 611S0 Call immediately "611" (Service hot-line) and do NOT wait for more digits
# |<411:16505551212S0> Substitute "411" with the Google-411 local number "16505551212" do NOT wait for more digits "S0"
# )
#
#
# Copy and past the following STRING into the DIALPLAN field of your device:
#
# L:20, ( P9 <:**officenumber**> | x | #x**xxS0 | #xS3 x. | ##x**xxS0 | ##xS3 x.| ####**xxS0 | ####S3 x. | #####x**xxS0 | #####xS3 x. | ######x**xxS0 | ######xS3 x. | **xxS1 | **xxxS0 | 1 [2-9]xx [2-9]xxxxxxS0 | <:1650> [2-9]xxxxxxS2 | <:1> [2-9]xx[2-9]xxxxxxS0 | 011 x. | 00 x. | 49 x. | 62 x. | 972 x. | 911S0 | 110S0 | 112S0 | 611S0 |<411:16505551212S0> )
#
#
# More details can be found here: http://www.cisco.com/en/US/docs/voice_ip_comm/csbpvs/spa9000/administration/guide/SPA9000_Voice_System_V6-1_AG_NC-WEB.pdf
#
#
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
# ******************************* Configuration *******************#
# This section is where you can change the behavior of all the #
# functions. Change these according to your needs. #
# *****************************************************************#
####################################################################
####################################################################
####################################################################
# It is possible to define your own "local" area code for making SS to SS
# calls. Dialing any number preceded by the value define will route a call
# internally, instead of making a call to a PSTN. If you do not wish to use
# this feature, leave it blank.
Area = '111' # my area code, this will be added to 7-digit dialouts
# The Time Zone offset based from GMT. Ie., London is 0, Paris is +1, New York
# is -5 and Kolkata is +5:30.
#
# !NOTE: It does not account for Daylight Savings, as it depends per country
# (and the server on which Sipsorcery is deployed)
#
# If unsure, visit http://www.timeanddate.com/worldclock/difference.html
#
Tz = -8 # my time zone (GMT format, e.g. Eastern = -5, Central = -6)
TimeToComplete = 45 # Time to complete the dial in seconds
CallRobbi = "**mycellnumber**@DIDLOGIC" # Best way to find my cell (DIALTHROUGH) for calls from Germany
# Specifies the canonical / IP host name(s) of the local SS server. Used to
# determine if a call is SS to SS, or SS to PSTN/URI
# Serviced domains, must be in lowercase!
Domains = ['sipsorcery.com','sip.sipsorcery.com','sip1.sipsorcery.com','sip2.sipsorcery.com','69.59.142.213']
Host = 'sipsorcery.com' # Replaces "host" on incoming calls / incoming calls will come with this host
# Uncomment next line and insert your White Pages API key, if you have it
#WP_key = '**WP-KEY**' # White Pages API key
#CNAM_User = 'CNAM-USER'
#CNAM_key = 'CNAM-KEY' # CallerIDservice API key
####################################################################
# *************** Google Voice Configuration Section **************#
####################################################################
HOMEaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 495-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
OFFICEaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 331-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
SHOPaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 495-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
TEST_HOMEaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 663-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
TEST_OFFICEaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 417-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
TEST_SHOPaccount = [{
:usr => 'myemail' , # Your GV login name, with our without @gmail.com
:pwd => 'password' , # Your GV password
:cb => '+1 (333) 502-1111' # my 10-digit Google-Voice Number (myemail@gmail.com)
}]
####################################################################
# *************** SIP Provider Configuration Section **************#
####################################################################
Local_HOME = VSP.new '#0' , ' ${EXTEN}@ Local-HOME' , 'Localphone Home route' , :tmo => 60 , :intPrefix => '00'
Local_Office = VSP.new '#1' , ' ${EXTEN}@ Local-OFFICE' , 'Localphone Office route' , :tmo => 60 , :intPrefix => '00'
Local_Shop = VSP.new '#2' , ' ${EXTEN}@ SSprovider-2' , 'Localphone Shop route' , :tmo => 60 , :intPrefix => '00'
SG_Germany = VSP.new '#3' , ' ${EXTEN}@ SG-Germany' , 'SIPGate GERMANY route' , :tmo => 60 , :intPrefix => '00'
DIDLOGIC = VSP.new '#4' , ' ${EXTEN}@ DIDLOGIC' , 'DIDLOGIC route' , :tmo => 60 , :intPrefix => ''
Google_HOME = GV.new '##0', nil , 'Google Voice (myemail@gmail.com) route' , :account => HOMEaccount , :repeat => 3, :rand => true, :tmo => 60 , :intPrefix => '011'
Google_Office = GV.new '##1', nil , 'Google Voice (myemail@gmail.com) route' , :account => OFFICEaccount , :repeat => 3, :rand => true, :tmo => 60 , :intPrefix => '011'
Google_Shop = GV.new '##2', nil , 'Google Voice (myemail@gmail.com) route' , :account => SHOPaccount , :repeat => 3, :rand => true, :tmo => 60 , :intPrefix => '011'
VSP.new '####' , 'DisableSafeGuards' # Disable safeguards prefix is ####
####################################################################
####################################################################
####################################################################
# Here we will set the SPECIFICS for each phone location #
# We use ONE script for all attached devices. Based on the NAME of #
# the dial plan we will adjust the local specifics. #
####################################################################
case sys.DialPlanName
when "HOME" # We use the DIALPLAN-Name to set the various variables for each SS-Account (you link a DIALPLAN with each SS-Account)
# ONE plan for all acounts
sys.Log("----- ENTERED HOME Script")
E911_Number = "911@911-HOME" # "911-HOME" is a SS-Provider, which is (in my case) registered with Callcentric and using their E911 Service (mapping Street Address with phone number)
Default_Route = DIDLOGIC # "DIDLOGIC" is a SS-Provider, which is (in my case) registered with DIDLOGIC (cheap calls)
Backup_Route = Local_HOME # "Local_HOME" is a SS-Provider, which is (in my case) registered with Localphone (cheap calls)
My_Number = "**homenumber**" # This is the Number which this Dialplan instance will be "representing" (Many of our numbers are HOSTED by Google ==> see voicemail pickup)
My_Telefon = "HOME-PHONE" # "HOME-PHONE" is a SS-Account; this is used to REGISTER my ATA-device with SS
GV_Mailbox = "##2" + My_Number # Number to call Google Voice
CLI_Name = My_Telefon # This is the caller NAME used with DIDLOGIC (set in "sys.SetFromHeader")
CLI_Number = My_Number # This is the caller ID used with DIDLOGIC (set in "sys.SetFromHeader")
VMaccess = "12223334444" # This is one of the numbers your Google Voice account sends calls to; ONLY those are allowed to pickup voice mail ... you need to configure access on the phone tab of your GV account settings
when "OFFICE"
sys.Log("----- ENTERED OFFICE Script")
E911_Number = "911@911-OFFICE"
Default_Route = DIDLOGIC
Backup_Route = Local_Office
My_Number = "**officenumber**"
My_Telefon = "OFFICE-PHONE"
GV_Mailbox = "##2" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
when "OFFICE-LSM"
sys.Log("----- ENTERED OFFICE-LSM Script")
E911_Number = "911@911-LSM"
Default_Route = DIDLOGIC
Backup_Route = Local_Office
My_Number = "12223334444"
My_Telefon = "OFFICE-LSM"
GV_Mailbox = "##2" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
when "SHOP" ####The Google NUMBER needs to be adjusted when transfer from RINGCENTRAL is done
sys.Log("----- ENTERED SHOP Script")
E911_Number = "911@911-SHOP"
Default_Route = DIDLOGIC
Backup_Route = Local_Shop
My_Number = "**shopnumber**"
My_Telefon = "SHOP-PHONE"
GV_Mailbox = "##1" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
when "HOME-TEST"
sys.Log("----- ENTERED HOME-TEST Script")
E911_Number = "911@911-HOME"
Default_Route = DIDLOGIC
Backup_Route = Local_HOME
My_Number = "**homenumber**"
My_Telefon = "HOME-TEST"
GV_Mailbox = "16316631218"
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
when "HOME-OFFICE"
sys.Log("----- ENTERED HOME-OFFICE Script")
E911_Number = "911@911-HOME"
Default_Route = DIDLOGIC
Backup_Route = Local_Office
My_Number = "**officenumber**"
My_Telefon = "HOME-OFFICE"
GV_Mailbox = "##2" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
when "HOME-SHOP" ####The Google NUMBER needs to be adjusted when transfer from RINGCENTRAL is done
sys.Log("----- ENTERED HOME-SHOP Script")
E911_Number = "911@911-HOME"
Default_Route = DIDLOGIC
Backup_Route = Local_Shop
My_Number = "**shopnumber**"
My_Telefon = "HOME-SHOP"
GV_Mailbox = "##1" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
else # Just in case we have an UNKNOWN dial plan, we set the HOME-TEST setting
sys.Log("----- ENTERED ***** BACKUP ***** Script")
E911_Number = "911@911-HOME"
Default_Route = DIDLOGIC
Backup_Route = Local_HOME
My_Number = "**homenumber**"
My_Telefon = "HOME-TEST"
GV_Mailbox = "##2" + My_Number
CLI_Name = My_Telefon
CLI_Number = My_Number
VMaccess = "12223334444"
end
####################################################################
####################################################################
####################################################################
# ------ END MANDATORY ENTRIES SECTION-----------------------------#
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
# --------BEGIN OPTIONAL ENTRIES SECTION---------------------------#
####################################################################
####################################################################
####################################################################
####################################################################
# --------BEGIN OPTIONAL SECTION FOR SPEED DIAL--------------------#
# Speed dial entries. Format: "short code" => "destination (POTS or SIP)"
Speeddial = {
#'1' => '#### #1 +1 (111) 283-4444', # Special Dial "NO-SAFEGUARD + Force-VSP + Number"
#'1' => '**mycellnumber**@SSprovider-1 & **wifecellnumber**@SSprovider-2 | **homenumber**@SSprovider-3' , # Example of a call to MULTIPLE SIP endpoints (numbers)
'1' => '**mycell**' , # @SSprovider-3&**homenumber**@SSprovider-1&12223334444@SSprovider-2|**mycellnumber**@SSprovider-2' , # Robbi Cell
'3' => '**wifecell**' , #
'4' => '**soncell**' , #
'**888' => '1234569951@sip.tropo.com', # International Dialtone
'**777' => '1234563416@sip.tropo.com', # TROPO Test
'911' => E911_Number , # Dial 911 via Callcentric (Location address is registered with them)
'112' => E911_Number , # German Firefighter # ==> Dial 911 Callcentric (Location address is registered with them)
'110' => E911_Number , # German Police # ==> Dial 911 via Callcentric (Location address is registered with them)
'**701' => 'skype@ippiskype' , # SKYPE me
'**999' => 'music@iptel.org' , # MUSIC for testing
'**411' => '+1 (800) 466-4411' , # Google's Directory Assistance, GOOG-411
'**303' => '303@sip.blueface.ie' , # Blueface speaking clock (Ireland time)
'**266' => '4153767253@podlinez.com' , # CNN Headlines (266 = "CNN")
'**222' => '8458266132@podlinez.com' , # ABC News - Nightline - Podcast (222 = "ABC")
'**677' => '6505236819@podlinez.com' , # NPR: Hourly News Summary Podcast (677 ="NPR")
'**932' => '7755333366' , # Columbus OH-based national weather (932 = "WEA[ther]")
# My OWN Speeddial Numbers from LOCALPHONE and DIRECT dial #
'**41' => '+1 9544732123' , # Amex
'**11' => '+972 123444444' , # grandma's CELL
}
# --------END OPTIONAL SPEED DIAL ENTRY SECTION--------------------#
####################################################################
####################################################################
# --------BEGIN OPTIONAL SECTION FOR CNAM LIST---------------------#
# CNAM table: number in ENUM format => caller's name (phonebook)
CNAM = {
'19544732123' => 'Amex' ,
'0097244444444' => 'Oma' ,
}
# --------END OPTIONAL SECTION FOR CNAM LIST-----------------------#
####################################################################
####################################################################
# --------BEGIN OPTIONAL SECTION FOR ENUM LIST---------------------#
# My own ENUM database
# This is used as a "shortcut" .... rather to dial using an outside SIP provider,
# we just move the call to a registered phone on our sipsorcery ACCOUNT.
# Look here for more detail: http://en.wikipedia.org/wiki/Telephone_number_mapping
MyENUM = {
'**homenumber**' => 'HOME-PHONE@local & HOME-TEST@local' , # We dial TWO extensions at the same time
'**officenumber**' => 'OFFICE-PHONE@local & HOME-OFFICE@local' , # "local" means SS will look for your phone under SS-ACCOUNTS
#'**shopnumber**' => 'SHOP-PHONE@local & HOME-SHOP@local'
}
# Enum database list
EnumDB = [
MyENUM, # look in MyENUM first
'e164.org',
'e164.info',
'e164.arpa',
'e164.televolution.net',
'enum.org',
]
# --------END OPTIONAL SECTION FOR ENUM LIST-----------------------#
####################################################################
####################################################################
# --------BEGIN OPTIONAL SECTION FOR WHO IS CALLING----------------#
# Caller entries. Format: "caller-id" => "action"
CallFrom = {
#'**mycellnumber**' => '**mycell**@SSprovider-1' , # If called from this number ==> forward to URI
#'**mycellnumber**' => 'test' , # If called from this number ==> forward to TEST
#'**homenumber**' => 'dialtone' , # If called from this number ==> give dialtone
#'12223334444' => 'tropotest' , # When I call from my CELL ==> testing mode
}
# --------END OPTIONAL WHO IS CALLING ENTRY SECTION----------------#
####################################################################
####################################################################
# --------BEGIN OPTIONAL SECTION FOR SAFEGARDS---------------------#
# Uncomment line below to enable misdialing safeguards
EnableSafeguards = 1
# Excluded Prefixes. Provides a safeguard against accidentally calling premium
# numbers. Accepts both strings and patterns, spaces ignored
ExcludedPrefixes = [
' 1 (900 | 976 | 809)', # USA Premium
' 1 \d\d\d 555 1212', # USA Directory assistance
'44 (9 | 55 | 70 | 84 | 87)', # UK Premium
'44 84 (4|5)', # UK Local Premium
'44 70', # UK Personal Premium
'43 (8|9)', # Austria Premium
'32 (7|90)', # Belgium Premium
'420 90', # Czech Premium
'45 (1 | 50 (1|2|3) | 70 (1|2))', # Denmark Premium
'45 (8|9) 0', # Denmark Premium (...)
'33 (7|9)', # France Premium
'49 (1 [^567] | 900)', # Germany Premium
'39 (1 | 84 | 89)', # Italy Premium (...)
'31 (14 | 6 (3|8|9) | 8 | 9)', # Netherlands Premium (...)
'48 (39 | (2|7|8) 0)', # Poland Premium
'46 9 (00 | 39 | 44)', # Sweden Premium
'41 90 (0|1|6)', # Switzerland Premium
]
# Yet another safeguard, list of blessed country codes
Allowed_Country = %w{ 1 31 39 43 44 49 61 62 65 972 506 }
# --------END OPTIONAL SECTION FOR SAFEGARDS-----------------------#
####################################################################
####################################################################
####################################################################
# These rules are NOT implemented yet
####################################################################
####################################################################
####################################################################
# Answer rules.
#
# Syntax: "Rule" => "Options"
#
# Where (CaSe Senitive!):
# Rule * Times between which calls will be answered, OR
# * "unavailable" : the rule when the user is unavailable, OR
# * "default" : the default rule, for which none of the other rules match.
# Options * "decline" : to decline the call with this rule, OR
# * One or more numbers to call.
#
# Multiple numbers separated by a '&' sign will be called simultaneously. All #
# phones will ring, until one of them is answered.
#
# Example: "12:00-14:00" => "homephone@asip.com&mobilephone@asip.com"
#
# Multiple numbers separated by a '#' will be called in the order
# listed. The numbers can be limited to a maximum "wait for answer" time by
# adding a '!' sign followed by the amount of seconds (15 seconds is the
# internal limit).
#
# Example: "12:00-14:00" => "homephone@asip.com!10#mobilephone@asip.com!10"
# This will call "homephone", ringing up to 10 seconds and if not answered will
# proceed to call "mobilephone", also ringing for up to 10 seconds
#AnswerRules = {
# "17:30-21:30" => "mobilephone@asip.com&homephone@asip.com",
# "21:30-23:00" => "homephone@asip.com",
# "23:00-6:00" => "decline",
# "6:00-17:30" => "officephone@asip.com!10#homephone@asip.com!5",
# "$unavailable" => "mobilephone@asip.com",
# "$default" => "#{sys.Username}@local",
# "18885551212" => "*3callback1#callback2"
#}
####################################################################
####################################################################
####################################################################
####################################################################
# --------END OPTIONAL ENTRIES SECTION-----------------------------#
####################################################################
####################################################################
####################################################################
####################################################################
#******************************************************************#
#******************************************************************#
#**** E N D O F C O N F I G U R A T I O N S E C T I O N ****#
#******************************************************************#
#******************************************************************#
####################################################################
####################################################################
####################################################################
####################################################################
# --------BEGIN FUNCTIONS / PROCEDURES ----------------------------#
####################################################################
####################################################################
####################################################################
####################################################################
# *************************** R O U T E _ T O *******************#
####################################################################
def route_to vsp, dest=nil, enum = EnumDB
sys.Log("----- ENTERED Route_To")
@num.gsub!(/[^0-9*+]/,'') # Delete all fancy chars (only digits, '+' and '*' allowed)
enum.to_a.each do |db| # if enum enabled, look in all enum databases
if uri = (db.class == Hash)? db[@num] : sys.ENUMLookup("#{@num}.#{db}")
sys.Log("-------------- ENUM entry found: '#{uri}' in #{db.class == Hash ? 'local' : db} database")
dial(uri); break
end
end # ENUM not found or failed, call via regular VSP
return unless vsp # No VSP - do nothing
prettyNum = @num
ExcludedPrefixes.each {|p| p.gsub!(/\s*/,''); sys.Respond(503,"Calls to #{$1}* not allowed") if @num =~ Regexp.new("^(#{p})")}
if @intCall then
@num = vsp.intPrefix + @num
end
uri = vsp.fmt.gsub(/\s+/,'').gsub(/\$\{EXTEN(:([^:}]+)(:([^}]+))?)?\}/) {@num[$2.to_i,$4? $4.to_i : 100]}
dest &&= " (#{dest})"; with = vsp.name; with &&= " with #{with}"
sys.Log("-------------- Calling #{formatNum(prettyNum)}#{dest}#{with}")
if vsp.is_gv?
vsp.repeat.times do |i|
@code, @reason = 200, "OK" # assume OK
sys.GoogleVoiceCall *vsp.getparams(uri, i + (vsp.rand ? @t.to_i : 0))
sys.Log("--------------ERROR: Google Voice Call failed!")
@code, @reason = 603, 'Service Unavailable'
end # Loop
else
# Only DIDLOGIC supports setting the CLI
if vsp.intPrefix == "" then
sys.SetFromHeader(CLI_Name, CLI_Number, nil)
sys.Log("-------------- CLI-Name #{CLI_Name} / CLI-Number #{CLI_Number}")
else
sys.SetFromHeader(nil, nil, nil)
sys.Log("-------------- CLI-Name NIL / CLI-Number NIL")
end
vsp.repeat.times do
dial(uri, @timeout || vsp.tmo || 300) # Dial, global time-out overrides account
end # Loop
end # Dialing via GV?
end
####################################################################
####################################################################
####################################################################
# ******************** s e l e c t V S P **********************#
####################################################################
def selectVSP # VoIP provider selection
sys.Log("----- ENTERED Select VSP with @num: #{@num}")
# Reject calls to premium numbers unless VSP was forced
ExcludedPrefixes.each {|p| p.gsub!(/\s*/,''); sys.Respond(503,"Calls to #{$1}* not allowed") if @num =~ Regexp.new("^(#{p})")}
case @num
when My_Number # My Google Voice number, when its called we go to our voice mail.
sys.Log("-------------- Route to VOICEMAIL")
sys.SetFromHeader(My_Telefon, VMaccess, nil) # We set the FROM-HEADER to be one of the forwarding numbers within your GV setup (PHONE-Tab on GV-Setup page)
sys.Log("-------------- URI call") # That number (VMaccess) is configured to lead us to VoiceMail if we call the Google-Number (My_Telefon)
sys.dial(My_Number + "@DIDLOGIC", TimeToComplete) # ONLY DIDLOGIC allows me to set the caller-id
sys.Log("--------------ERROR: Route to VOICEMAIL failed")
status() # We shouldn't be here! Get error code...
sys.Log("--------------ERROR: Call failed: code #{@code}, #{@reason}")
route(nil,nil) # let the calling function know that we did have an error
when /(^1([2-9]\d\d)[2-9]\d{6})/ # North America
@num = $1 # Truncate to 11 digits
case $2 # check area code
#############################################################################################
### UN-COmment if you choose to use a "normal" VOIP provider
#############################################################################################
when "800", "866", "877", "888" # toll free numbers...
sys.Log("-------------- Default Route to TOLLFREE")
route_to Default_Route, "USA toll-free", nil
else
sys.Log("-------------- Default Route to US & Canada ")
route_to Default_Route, 'Default US & Canada route' # all other destinations within US & Canada
#############################################################################################
#############################################################################################
### UN-COmment if you choose to use Google Voice as your VOIP provider
#############################################################################################
# Google Voice settings
#when "800", "866", "877", "888" # toll free numbers...
# sys.Log("-------------- GoogleVoiceCall to TOLLFREE")
# route_to VSP.tab[GV_Account], "USA toll-free", nil
#else
# sys.Log("-------------- GoogleVoiceCall to US & Canada ")
# route_to VSP.tab[GV_Account], 'Default US & Canada route' # all other destinations within US & Canada
#############################################################################################
end
#############################################################################################
### UN-COmment if you choose to use Google Voice as your VOIP provider
#route_to Default_Route, 'Default Route', nil # If GV call failed, try one more time with our Default_Route
#############################################################################################
route_to Backup_Route, 'Backup Route', nil # If MAIN call failed via Default_Route, try one more time with our Backup_Route
when /^972/ # Israel
case $1 # check area code
when /^(5|6)/ then # Israel Mobile
route_to Default_Route, 'Destination - Israel Mobile', nil
else # Israel Land
route_to Default_Route, 'Destination - Israel Land', nil
end
route_to Backup_Route, 'Backup Route', nil # If MAIN call failed via Default_Route, try one more time with our Backup_Route
when /^49/ # Germany
case $1 # check area code
when /^(5|6)/ then # Germany Mobile
route_to Default_Route, 'Destination - Germany Mobile', nil
else # Germany Land
route_to Default_Route, 'Destination - Germany Land', nil
end
route_to Backup_Route, 'Backup Route', nil # If MAIN call failed via Default_Route, try one more time with our Backup_Route
else
rejectCall(603,"Number's too short, check & dial again") if @num.length < 9
route_to Default_Route, 'Default route applied', nil
end
end
####################################################################
####################################################################
####################################################################
# **************************** C H E C K N U M *****************#
####################################################################
def checkNum
@num.match(/^\D/) && return # skip if number doesn't begin with a digit
# Reject calls to not blessed countries and premium numbers
# (unless VSP was forced using #n dial prefix)
rejectCall(503,"Calls to this country not allowed") unless @num.match "^(#{Allowed_Country.join('|')})"
rejectCall(503,"Calls to #$&* not allowed") if @num.match '^(' + ExcludedPrefixes.map { |x| "(:?#{x.gsub(/\s*/,'')})" }.join('|') + ')'
end
####################################################################
####################################################################
####################################################################
# ************************** to_ENUM ****************************#
####################################################################
def to_ENUM num
num.gsub!(/[^0-9*+#]/,'') # Delete all fancy chars (only digits, '+' , "#", and '*' allowed)
# Check if the number begins with one of international prefixes:
# '+' - international format
# 00 - European style international prefix (00)
# 011 - US style international prefix (011)
num =~ /^(\+|00|011)/ and return $' # if yes, remove prefix and return
case num # Special cases
when /^[2-9]\d{6}$/ # Local call, 7-digit number
'1' + Area + num # prefix it with country and area code
when /^[01]?([2-9]\d{9})/ # US number with or without "1" country code
'1' + $1 # add country code and truncate number to 10-digit
when / #/
num # ... as is
else
rejectCall(603,"Wrong number: '#{num}', check & dial again")
end
end # to_ENUM
####################################################################
####################################################################
####################################################################
# ************************** Logger *******************************
####################################################################
# This simplifies the LOGGING / DEBUGGING of your dialplan
def l(lname,lwert)
sys.log("*****Die VARIABLE #{lname} hat den WERT: #{lwert}")
end
####################################################################
####################################################################