My "One for All" Ruby plan ** Updated 08-Oct-08

Catalog of dial plans
lux
Posts: 8
Joined: Fri May 22, 2009 3:06 pm

Dailplan Disappears

Post by lux » Fri Jun 26, 2009 9:33 am

If i copy the dailplan from post #1 into the dailplan field (with the "require" issue solved before) it says:
Dial plan extensions successfully updated 26 Jun 2009 10:28:55.
but if i click again on the "Configuration" button, the dailplan field is clear again. it's no dailplan inside!

Why?
Is it possible, that the dailplan was loaded although correctly?
Does anybody have had the same problem?

Jochem
Posts: 5
Joined: Sun Jul 25, 2010 7:39 am

Re: My "One for All" Ruby plan ** Updated 08-Oct-08

Post by Jochem » Sun Jul 25, 2010 7:47 am

The dialplan raises an exception when I try to make an outgoing call.

Unfortunately, my ruby knowledge is very limited. Can someone tell
what's wrong?

Exception:

DialPlan=> ** Error: undefined method `fixupNumber' for
#<TNumber:0x0000370>

fixupNumber seems to be defined, but like I said I don't know much about ruby, so maybe the method is not defined for this type or something. I can't seem to figure it out, nor do I understand why I seem to be the only one with this problem.

Thanks.

Code: Select all

#Ruby
    # Original by MikeTelis (http://www.mysipswitch.com/forum/viewtopic.php?t=706)
    #
    # Adapted by Mike Green as following:
    #
       

    # ******************************* Configuration *******************************
    # This section is where you can change the behavior of all the functions.
    # Change these according to your needs.
    # *****************************************************************************

    # Specifies the host name required to place a local (MSS to MSS) call.
    #
    # LocalDomain = "sip.mysipswitch.com"
    LocalDomain = "sip.mysipswitch.com"

    # Specifies the canonical / IP host name(s) of the local MSS server. Used to
    # determine if a call is MSS to MSS, or MSS to PSTN/URI
    #
    # Domains = [LocalDomain, "213.200.94.182"]
    Domains = [LocalDomain, "213.200.94.182"]

    # It is possible to define your own "local" area code for making MSS to MSS
    # calls. Dialing any number preceeded 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.
    #
    # LocalAreaCode = ""
    LocalAreaCode = "026"

    # Specifify if a 9 needs to be dialed to make a call outside of the local
    # MSS work. If enabled, a call to 5551212 would be routed to 5551212@(LocalDomain)
    # and a call to 95551212 would be routed to 5551212@(a_sip_provider).
    #
    # This function cannot be combined with the LocalAreaCode option.
    #
    # DialNineOut = true
    DialNineOut = false

    # Enabling this option forces the User ID to be used the caller ID (if supported
    # by the provider).
    #
    # UserIDAsOutgoingCallerID = false
    UserIDAsOutgoingCallerID = false

    # Your local country code. This is used to replace the leading 0. For example,
    # a number dialied as 0203112233 in the Netherlands would be converted to
    # 31203112233 if MyCountryCode = "31".
    #
    # For North America (Country Code 1), the number will be prepended to the
    # dialed number, unless it is already present. Ie., 2125551212 will become
    # 12125551212.
    #
    # Use MyCountryCode = "" if no conversion is desired.
    #
    # MyCountryCode = ""
    MyCountryCode = "31"

    # 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 MySipSwitch is deployed)
    #
    # If unsure, visit http://www.timeanddate.com/worldclock/difference.html
    #
    # MyTimeZone = "-5"
    # MyTimeZone = "+5:30"
    MyTimeZone = "+1"

    # Specify whether ENUM lookup should be used as the preferred method of calling.
    #
    # You can override this function by dialing the number with *9
    #
    # UseENUM = false
    UseENUM = true

    # Default Callback Number. This number will be used in case the bridge/callback
    # option is used, but no 2nd number was dialed.
    #
    # If the entry is empty, the default will be "yourself", as in
    # <sip:yourusername@mysipswitch.com>
    #
    # DefaultCallbackNumber = ""
    DefaultCallbackNumber = ""

    # Specify how long one particular number should ring until the next number in
    # the list is dialed.
    #
    # DefaultDelay = 10
    DefaultDelay = 10

    # Speed Dial numbers.
    #
    #   Syntax: "(number)" => "(actual number or URI)"
    #
    # NOTE: It is valid to use special functions in Speed Dial!
    #
    # Speeddial = { "0" => "303@sip.blueface.ie", "1" => "**500@voxalot.com" }
    Speeddial = {
       "9901" => "613@fwd.pulver.com",   # Echo test USA
       "9949" => "enum-echo-test@sip.nemox.net", # Echo test Germany
       "9944" => "sip:904@mouselike.org", # Call quality test UK   
       "303" => "303@sip.blueface.ie",   # Calls speaking time @ blueface
       "612" => "612@fwd.pulver.com"   # Calls speaking time @ pulver
    }

    # Providers table.
    #
    #   Syntax: "Key" => "[Prefix]@Provider"
    #
    #   Where:
    #      Key         A single digit, 0 being the default.
    #      Prefix      Optional prefix that needs to be added to the dialed number.
    #      Provider   Provider by name, as listed in MySipSwitch configuration.
    #
    # You can override the provider by dialing a number with the prefix *1 and then
    # the key. For example:
    #
    #   *1412125553456 dials 12125553456 using the provider at key 4
    #
    # VSPtable = { "0" => "@ provider1", "1" => "@ provider2" }
    VSPtable = {
      "0" => "@12voip",      # default provider (prefix numbers with 00)
      "1" => "@budgetphone"      # budgetphone
    }

    # Provider rules.
    #
    #   Syntax: "Rule" => "Provider"
    #
    #   Where:
    #      Rule      A regular expression (Regexp) to match against a number
    #      Provider   Provider by key, as listed in VSPtable above
    #
    # NOTE: Use a double backslash for a single one!
    #
    # VSPRules { "^\\*1" => "0", "^\\*2" => "1" }
    VSPRules = {   
       "^#{MyCountryCode}|^0"          => "0" # A national (local) number
#       "^[1]800|866|877|888\\d{7,7}$"   => "4", # North America Toll Free numbers
#       "^1[2-9]\\d{9,9}$"             => "2"   # North America
    }

    # 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 seperated 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 seperated 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"
    }

    # Excluded Prefixes. Provides a safeguard against accidentally calling premium
    # numbers.
    #
    #   Syntax: "(number)"
    #
    #   Where:
    #      (number)   Any number(s) at the start of a dialed number
    #
    # The numbers need to start with the country code. You can also use this to
    # block entire numbers from being dialed. To override this function, dial the
    # number with *2.
    #
    #    *219005553456 dials 19005553456, bypassing the safeguard
    #
    # ExcludedPrefixes = [ "118118", "411", "1900" ]
    ExcludedPrefixes = [ 
       "1900", "1976",                # USA Premium
       "449", "4455", "44870", "44871",   # UK Premium 
       "44844", "44845",               # UK Local Premium
       "4470",                        # UK Personal Premium
       "438", "439",                  # Austria Premium
       "327", "3290",                  # Belgium Premium
       "451", "45501", "45502", "45503",    # Denmark Premium (...)
       "45701", "45702", "4580", "4590",    # Denmark Premium 
       "337", "339",                  # France Premium
       "491", "49900",                  # Germany Premium
       "391", "392", "394", "395",       # Italy Premium (...)
       "396", "397", "398", "399",         # Italy Premium
       "3114", "3163", "3168", "3169",    # Netherlands Premium (...)
       "318", "319",                  # Netherlands Premium   
       "4839", "4820", "4870", "4880",      # Poland Premium
       "46900", "46939", "46944",         # Sweden Premium 
       "41900", "41901", "41906"         # Switzerland Premium
    ]

    # ********************************** DEFINES **********************************
    # For basic functionality of this plan, it should not be neccesary to
    # edit the code below.
    # *****************************************************************************

    # DO NOT CHANGE THE TWO LINES BELOW!
    Sys = sys
    Req = req

    # TNumber class
    #
    # Container for each particular number, with a seperate handler
    #
    class TNumber
       attr_reader :number, :provider, :override, :enum, :useenum, :timeout
       attr_writer :number, :provider, :override, :enum, :useenum, :timeout
       
       def initialize(aNumber)
          @number = fixupNumber(aNumber)
    #      @number = Speeddial[@number] if (Speeddial[@number])
          
          @provider = ""
          @override = false   # Used for overriding excluded prefixes
          @useenum = UseENUM
          @enum = ""         # Initialize ENUM var
          
          @timeout = extractDialTimeout(@number)
       end   
          
       # Prepares the number for dialing.
       #
       def prepare   
          return 0,"" if is_URI?

          # sub! below removes prefixes:
          #  '+' - international format
          #   00 - European style international prefix (00)
          #  011 - US style international prefix (011)
          #  810 - Russian style international prefix (810)

           unless @number.sub!(/^(\+|00|011|810)/,"")         
             # Convert a national number to an international number         
             case MyCountryCode
                # North America
                when "1"
                   # Prepend a North American number with the country code,
                   # unless it already starts with the country code
                   @number = MyCountryCode + @number if @number =~ /^[^1]/
              
            
                # Russia (From MikeTelis' original code)
                when "7"
                   case @number
                      when /^82\d{7,7}$/
                         @number = "7496" + @number[2..-1]
                      when /^8/
                         @number[0] = "7"
                      when /^[1-9]\d{6,6}$/
                         @number = "7495" + @number
                   end
                  
              else
                # Apply default rule (replace 0 with country code), unless
                # MyCountryCode is not specified.
                        
                @number.sub!(/^0/, MyCountryCode) unless MyCountryCode.empty?

              end
            end
     
          # Check if we can override the prefix, and if not, see if it's in
          # the list of exluded prefixes.
          if !@override and hasExludedPrefix = ExcludedPrefixes.find {|prefix| @number =~ /^#{prefix}/ }
             return 403,"Numbers starting with #{hasExludedPrefix} are not permitted"
          end
                           
            # If the provider was not specified by the user, we will decide it here
            if @provider.empty?
              getEnum if @useenum
              selectProvider
            end
            
            return 0,""
       end

       # Selects the provider based on the number.
       #
       def selectProvider 
          # Fix North American numbers that are longer than usual      
          @number = $1 if @number =~ /(^1([2-9]\d\d)\d{7,7})/
        
            @provider = "0" # Set the default provider first
       
          VSPRules.each { |aRule|
             if @number =~ /#{aRule[0]}/
                @provider = aRule[1]
                break
             end
          }      
       end

       # Extracts the timeout specified with the number
       def extractDialTimeout(aNumber)
          return aNumber.sub!(/\!(\d{1,2})/, '') ? $1.to_i : 0
       end
       
       # Are we using the ENUM to call?
       #
       def use_ENUM?
          return !@enum.to_s.empty?
       end
       
       # Is it a full URI instead of a number?
       #
       def is_URI?
          return @number =~ /@/
       end
       
       # Expands the number based on the providers' template, to be used
       # in Sys.Dial
       #
       def expandNumber   
          if tpl = VSPtable[@provider]   
             return tpl.sub(/\s*@\s*/) {|x| @number+"@"}
          else
             return @number
          end
       end

       # Sets the enum variable, if an ENUM is available
       #
       def getEnum   
          Sys.Log("Attempting to retrieve ENUM for #{@number}")
          @enum = "" unless @enum = Sys.ENUMLookup("+#{@number}.e164.org").to_s
          Sys.Log("Result ENUM lookup: '#{@enum}'")
       end
       
       private :getEnum
    end

    # TDialList class
    #
    # Controls the numbers and call methods
    #
    class TDialList   
       attr_reader :bridgenumbers
       
       MaxItems = 10
       
       def initialize
          @numbers = Array.new
          
          @bridgenumbers = false
       end
       
       # Add a number to the list
       #
       def append(aNumber)
          return 500,"Exceeded limit or class error" if (@numbers.length == MaxItems) or (aNumber.class.name != "TNumber")
          
          if !aNumber.is_URI?
             Code,Reason = processSpecialFunctions(aNumber)
             return Code,Reason if Code > 0
          end
                      
          @numbers.push(aNumber)
          
          return aNumber.prepare
       end
             
       # How many numbers do we have?
       #
       def length
          @numbers.length
       end
       
       def deleteFirst
          @numbers.shift
       end
       
       def deleteLast
          @numbers.pop
       end
       
       # Access to the numbers, by index (key) or phone number
       #
       def [](key)
          return @numbers[key] if key.kind_of?(Integer)
          return @numbers.find { |aNumber| key == aNumber.number }
       end
       
       # Handles any special function present in the number
       #
       # Special Functions:
       #
       #   *1(key)      Override the provider with the one specified in (key)
       #   *2         Bypass premium number safeguard
       #   *3         Bridge (callback) the numbers
       #   *9         Override ENUM setting (enable if disabled, and vice versa)
       #   *0         Trace the phone call
       #   **         Dial a *
       #
       def processSpecialFunctions(aNumber)
           while aNumber.number.sub!(/^\*([^\*])/, "")   
             case $1
                 # Special function 1 - Override provider
                when "1"
                   aNumber.number.sub!(/^(.)/, "")
                   aNumber.provider = $1;

                    return 400,"Invalid provider selected #{$1}" if VSPtable[aNumber.provider].to_s.empty?
                      
                    Sys.Log("! Overriding service provider for #{aNumber.number} to #{aNumber.provider}, template #{VSPtable[aNumber.provider]}")

                # Special function 2 - Bypass safeguard                            
                when "2"
                   Sys.Log("! Bypassing premium number safeguard for #{aNumber.number}")
                   aNumber.override = true

                # Special function 3 - Bridge the numbers in the list (will take only first two)
                when "3"
                   Sys.Log("! Request to bridge #{aNumber.number}")
                   @bridgenumbers = true
                
                # Special function 0 - Trace this particular call
                when "0"
                   Sys.Log("! Requested a trace for this call.")
                   Sys.Trace = true               
                   
                # Special function 9 - Override the use of ENUM
                when "9"
                   Sys.Log("! Override use of ENUM")
                   aNumber.useenum = !aNumber.useenum
             
                # Unknown function
                else
                   Sys.Log("! Unknown function in dial sequence found: #{$1} - Ignoring")
             end
           end
       
           # A double ** gets treated as a single * to dial
           aNumber.number.sub!(/^\*/,"")
          
           return 0,""
       end   

       # Make the call
       #
       def dial(*args)
          if Sys.Out and UserIDAsOutgoingCallerID
             Req.Header.From.FromName = Req.Header.From.FromURI.User.to_s
          end
          
          if @bridgenumbers
             # If no default callback number is set, use local user
             DefaultCallbackNumber = "#{Sys.Username}@local" if DefaultCallbackNumber.empty?

             number1 = @numbers[0].use_ENUM? ? @numbers[0].enum : @numbers[0].expandNumber
             number2 = (length < 2) ? DefaultCallbackNumber : @numbers[1].use_ENUM? ? @numbers[1].enum : @numbers[1].expandNumber
             
             Sys.Log("* Initiating bridge between #{number2} and #{number1}")
             Sys.Callback(number2, number1, 3) # 3 seconds before dialing
          else
             # If there's more than one number in the list, try each one until
             # one is picked up. (No ring timeout for single number)
                      
             ringtimeout = 0
             @numbers.each { |n|
                   numbertd = n.use_ENUM? ? n.enum : n.expandNumber
                               
                   # If there's more than 1 number to call, set the timeout if present.
                   ringtimeout = n.timeout == 0 ? DefaultDelay : n.timeout if (length > 1)
                   
                   if ringtimeout == 0
                      Sys.Log("* Dialing #{numbertd}")
                      Sys.Dial(numbertd)               
                   else
                      Sys.Log("* Dialing #{numbertd} with timeout #{ringtimeout}")
                      Sys.Dial(numbertd, ringtimeout)
                   end               
             }         
          end

          return status
       end   
       
       # Grab the status from the LastDialied list (Another great piece by MikeTelis)
       #
       def status(li=0)
          if (ptr = Sys.LastDialled[li]).nil?
             return 487,"Cancelled by MSS"
          else
              ptr = ptr.TransactionFinalResponse # SIPTransaction & SIPResponse
              return ptr.StatusCode,ptr.ReasonPhrase
          end
          
          return 0,""
         end
    end

    # Inbound Call Manager. Uses a rule-based table to determine where
    # an incomming call should be routed to, based on time of day and
    # availability.
    #
    class TInboundMgr
       attr_reader :time
       
       @@localuser = "#{Sys.Username}@local"
       
       def initialize
          @time = Time.now.gmtime   # In case this SIP Switch is deployed outside Dublin
                
          # Some timezones have half hour and 45 minute differences. Account for this.
          # It does NOT account for daylight savings!
          mtz = MyTimeZone.split(":")
          mtz[0] = '0' if mtz[0].to_s.empty?

          @time += mtz[0].to_i * 3600
          @time += mtz[0][0].chr == "-" ? ("-#{mtz[1]}".to_i * 60) : (mtz[1].to_i * 60) unless mtz[1].to_s.empty?

          Sys.Log("Using #{@time} to determine Answer Rule")
          
          callerid_name = Req.Header.From.FromName.to_s
          
          # Some SIPs simply leave the name blank, which some softphones don't
          # appreciate
          callerid_name = Req.Header.from.FromURI.User.to_s if callerid_name =~ /^$|\D/
          
          # Replace any characters other than A..Z or numbers. This could happen
          # with SIPBroker for instance ("Calgary,AB <sip:xxx@sipbroker.com>)
          callerid_name.gsub!(/[^a-zA-Z0-9]/, " ");
       
          # Add a 1 if it's a US 9-digit number.
          callerid_name = ("1" + callerid_name) if callerid_name =~ /^[2-9]\d{9,9}$/
          
          # Be careful with changing headers. You could end up spending a lot of
          # time debugging, checking why a call isn't going through! (Been there!)
          Req.Header.from.FromURI.User = callerid_name
          Req.Header.From.FromName = callerid_name
          
          @NumbersToCall = TDialList.new      
       end
       
       def Answer
          # Grab the rules
          tr = getTimeRule
          ur = getUnavailableRule
       
          # Insert unavailable rule, if needed
          unless ur.empty?
             tr.gsub!(/#{@@localuser}/, ur) if !Sys.IsAvailable
          end      
          
          Sys.Log("Answer Rule used: #{tr}")
          
          # Start dialing each number in the rule, unless rule is set to decline
          unless tr == "decline"
             tr.split("#").each  { |number|
                Code,Reason = @NumbersToCall.append(TNumber.new(number))
                
                # If there was an error adding the number, don't let it break
                # the answer rules, just remove it from the numbers to call.
                @NumbersToCall.deleteLast if Code > 0
             }

             @NumbersToCall.dial
          end
          
          # If we end up here, that means the numbers dialed weren't answered or
          # the rule is set to decline the call.
          Sys.Log("Exhausted answer options (or decline rule).")
          return 408, "#{@@localuser} is not available"
       end
       
       # Returns the time rule, based on the current sys time. Will return
       # a default rule if no time rule exists.
       #
       def getTimeRule
          result = ''
          
          AnswerRules.each { |rule|
             # If the rule contains a from-to time format
             if rule[0].match(/^(\d{1,2}):(\d{2,2})-(\d{1,2}):(\d{2,2})$/)            
                # From what time do we start to check?
                t1 = Time.gm(@time.year, @time.month, @time.day, $1.to_i, $2.to_i)
                
                # And until what time? (We decrease the time by a second)
                t2 = Time.gm(@time.year, @time.month, @time.day, $3.to_i, $4.to_i)
                t2 -= 1
                
                # If the start time is beyonthe end time, decrease start time
                # by 24 hours
                t1 -= (3600 * 24) if t1 > t2
                            
                result = rule[1] if @time.between?(t1,t2)
             else
                unless rule[0] =~ /^\$/
                   result = rule[1] if Req.Header.From.FromName.to_s =~ /#{rule[0]}/
                end
             end
          }
          
          return result if !result.to_s.empty?
          
          # If we end up here, it means we couldn't find a matching time rule.
          # So we look for a default rule. If none, we make a default rule.
          if AnswerRules["$default"]
             return AnswerRules["$default"]
          else
             return @@localuser
          end      
       end
       
       # Returns the rule for handeling unavailable user. Will return
       # empty if no rule available.
       #
       def getUnavailableRule
          return AnswerRules["$unavailable"].to_s
       end
    end

    # A helper for figuring out if the number is:
    #   1) a local call (MSS user -> MSS user)
    #   2) an URI call (MSS user -> SIP Provider user)
    #   3) a dialed phone call (MSS user -> PSTN)
    #
    def fixupNumber(aNumber)
       number = String.new(aNumber =~ /^(.+)@(.+)$/ ? $1.to_s : aNumber)
       host = $2.to_s.downcase
       port = host.sub!(/\:(\d+)/, "") ? $1 : ""

       if (host == "local")
          # It's a MSS user -> MSS user call
          number << "@" << LocalDomain

       elsif (host == "") or (Domains.find{|x| x.downcase == host})
          # It's a MSS user -> PSTN call, unless LocalAreaCode is matched.
          # A LocalAreaCode is not valid if a 9 needs to be dialed for outgoing calls.

          if (!LocalAreaCode.empty?) and (!DialNineOut)
             # We have a LocalAreaCode, but we'll also check in case it was
             # dialed with the country code (if specified)
             LACC = LocalAreaCode.gsub(/^0/, MyCountryCode)
          
             if number.sub!(/^#{LocalAreaCode}/,"") or (number.sub!(/^#{LACC}/, "") unless MyCountryCode.empty?)
                number << "@" << LocalDomain
             end
          elsif DialNineOut
             number << "@" << LocalDomain unless number.sub!(/^9/, "")
          end

       else
          # It's a MSS -> URI call
             
          number << "@" << host
       end
                   
       number << ":" << port unless port.empty?

       return number
    end

    # *********************************** MAIN ************************************
    # This is where all the action happens, depending on incomming or outgoing calls
    # *****************************************************************************
    begin
       timeit = Time.now
       
       Sys.Log("** Call from #{Req.Header.From.ToString} to #{Req.URI.ToString} **")

       Code = 500
       Reason = 'Internal error'
       
       if Sys.In   # Incoming call...
          InboundManager = TInboundMgr.new
          Code,Reason = InboundManager.Answer

       else # Outbound call ...      
          dest = String.new(Req.URI.ToString.to_s)
          dest.sub!(/^sip:/, "") # strip "sip:"
          dest.gsub!(/%../) {|x| x[1,2].to_i(16).chr}   # Convert %hh into ASCII
       
          # Is it a Speeddial? (Nested speeddial no longer supported, "adest" is
          # simply a temporart placeholder.
          adest = fixupNumber(dest)      
            dest = Speeddial[adest] if (Speeddial[adest])
         
          # Create a new Dial List
          NumbersToCall = TDialList.new     
       
          # Grab the phone number(s), seperated by a '#'
          dest.split("#").each { |number|
             # Add the number.
             Code,Reason = NumbersToCall.append(TNumber.new(number))

             # Did anything bad happen while adding this number?
             break if Code > 0
          }
       
          # Will stop script here if Code >= 200, ie error adding number
          Sys.Respond(Code, Reason) if Code > 0
        
          Code,Reason = NumbersToCall.dial
       end
       
       Sys.Respond(Code, Reason)
       
    rescue
       # Gives a lot more details at what went wrong. Don't worry about the Thread Exit.
       Sys.Log("** Error: " + $!) unless $!.to_s =~ /Thread was being aborted./
       
    ensure
       Sys.Log("Time to complete Dial Plan: " + (Time.Now - timeit).to_s)
    end

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: My "One for All" Ruby plan ** Updated 08-Oct-08

Post by MikeTelis » Sun Jul 25, 2010 9:40 am

Seems like this dialplan's been abandoned. Unless the author shows up to help, you're on your own.

Jochem
Posts: 5
Joined: Sun Jul 25, 2010 7:39 am

Re: My "One for All" Ruby plan ** Updated 08-Oct-08

Post by Jochem » Sun Jul 25, 2010 1:47 pm

Okay, but it seems to me that someone with some ruby-knowledge should be able to answer this.

Or else, do you know of any more recent universal dialplans available?

MikeTelis
Posts: 1582
Joined: Wed Jul 30, 2008 6:48 am

Re: My "One for All" Ruby plan ** Updated 08-Oct-08

Post by MikeTelis » Sun Jul 25, 2010 2:42 pm

Why don't you try Flexible table-controlled dialplan, Version 2?

See, sometimes it's easier to write your own, brand new program than fighting the bugs in somebody else's code. At a glance, I see problems with dynamically redefined constants (Code, Reason). I also had problems with safeguard table borrowed from this dialplan; finally, I had to give it up and start from the scratch.

Jochem
Posts: 5
Joined: Sun Jul 25, 2010 7:39 am

Re: My "One for All" Ruby plan ** Updated 08-Oct-08

Post by Jochem » Sun Jul 25, 2010 3:07 pm

Okay, I will try that :)

Post Reply