Archive for the ‘Ruby Dial Plans’ Category

The Default Ruby Dial Plan Demystified

Tuesday, August 5th, 2008

Default Ruby dial plan line by line.

When getting started, the default Ruby dial plan can be a bit hard to understand and many people don’t really know what to edit inside. This small article is aiming at explaining the basics so you can get started easier.

The first thing to mention is that with My SIP Switch there are 2 (very) different syntaxes for the dial plans. The “old one” is based on Asterisk syntax and using lines like that: “exten => …”. The new one is based on Ruby scripting and his much more powerful. You cannot use both syntaxes in the same dial plan! You need to pick one.

Here is the default Ruby dial plan (as of July 2008 and minus a few comments for clarity):

#Ruby

sys.Log(”call from #{req.Header.From.FromURI.ToString()} to #{req.URI.User}.”)

if sys.In then

# Do your incoming call processing customisations here.

sys.Dial(”#{sys.Username}@local”)

else

# Do your outgoing call processing customisations here.

case req.URI.User

when /^303$/ then sys.Dial(”303@sip.blueface.ie”)

when /^612$/ then sys.Dial(”612@fwd.pulver.com”)

when /^\*1/ then sys.Dial(”${dst:2}@provider1″)

when /^\*2/ then sys.Dial(”${dst:2}@provider2″)

when /^\*3/ then sys.Dial(”${dst:2}@provider3″)

else sys.Dial(”provider1″)

end

end

A Ruby dial plan must start with the line (Never remove that line):

#Ruby

The lines starting by # are comments. They are not interpreted as part of the dial plan. I removed most of them here.

The line:

sys.Log(”call from #{req.Header.From.FromURI.ToString()} to #{req.URI.User}.”)

will “log” all calls into the monitoring page. That allows to keep track of what’s going on and also to debug when you are testing the service.

The syntax is the following: sys.Log(” my log here “)

If you want to insert a variable into a log, you can use #{variable_name} for instance : #{req.URI.User}, as you’ve seen in the example above.

Then, starts the actual dial plan!

Inbound and outbound calls are clearly separated with the following structure:

if sys.In then

# INbound calls here

else

# OUTbound calls here

end

When you receive a call: sys.In will be equal to “True” and only the code between “then” and “else” will be interpreted.

The next line, starting with a #, is not interpreted. It’s a comment.

Incoming calls:

sys.Dial(”#{sys.Username}@local”)

That line, when interpreted, will call the phone which is registered to My SIP Switch.

sys.Username is a variable as is, it must not be changed! It will be equal to your actual username. Don’t do anything like that: sys.JohnSmith ; that would trigger an error.

If you want to receive your incoming calls on another phone, you can edit this line like that:

sys.Dial(”123456@myprovider”)

Where 123456 is the number you want to dial with the provider: myprovider (the provider’s name used here are the ones you set up when adding a new provider, in the 1st field).

That’s it of the incoming calls on this guide.

If you need further help, you can refer to this article:

Inbound Call Management with Ruby Dial Plans

You can also refer to these threads on the forum:

http://www.mysipswitch.com/forum/viewtopic.php?t=139

http://www.mysipswitch.com/forum/viewtopic.php?t=399


Then for the outgoing calls, by default we have:

case req.URI.User

when /^303$/ then sys.Dial(”303@sip.blueface.ie”)

when /^612$/ then sys.Dial(”612@fwd.pulver.com”)

when /^\*1/ then sys.Dial(”${dst:2}@provider1″)

when /^\*2/ then sys.Dial(”${dst:2}@provider2″)

when /^\*3/ then sys.Dial(”${dst:2}@provider3″)

else sys.Dial(”provider1″)

end

case req.URI.User is another test based on “pattern” which include several possibilities: each when represent a different situation if the outgoing call can’t be match to any of those cases then my SIP switch will follow the else rules.

As pattern match tool, we are using Regular Expressions (everything between /^ and / is a regular expression).

when /^303$/ then sys.Dial(”303@sip.blueface.ie”) means that when you dial 303 on your SIP phone. You will hear Blueface speaking clock.

when /^612$/ then sys.Dial(”612@fwd.pulver.com”) means that when you dial 303 on your SIP phone. You will hear FWD speaking clock.

when /^\*1/ then sys.Dial(”${dst:2}@provider1″)

Any number starting by *1 will match this case. Note that the * is a special character so we need a \ before it. ${dst:2} is representing the number you dialed minus the 2 first digits (*1 here).

If you called your provider something different than “provider1″ you’ll need to modify this! It must be one of the names you set as provider. If you don’t do that, when calling, you’ll notice an error message in the monitoring page saying : “Cannot resolve provider1″.

when /^\*2/ then sys.Dial(”${dst:2}@provider2″)

when /^\*3/ then sys.Dial(”${dst:2}@provider3″)

Same thing with *2 and *3.

else sys.Dial(”provider1″) Forward outgoing calls to provider1.

If you dialed a number which doesn’t start by *1, *2 or *3 then this line will be used. That’s the provider by default. Note that there is not ${dst} involved, since here you don’t need to remove any digit but to dial the number as is.

If you wanted to match any UK number and dial them with a specific provider you can do something like that:

when /^0044.*/ then sys.Dial(”0${dst:4}@ukprovider”)

Any number starting by 0044 will match the case, and then we remove the 0044 and replace that by a 0 (to adjust to local dialing). Then the resulting number is called via the provider named: ukprovider.

Then we have the closing tags “end” of the IF and of the CASE. Make sure not to remove them!

Remember that, this is a basic guide so I mentioned only a few possibilities of the software. If you want to go further you can refer to our forum and blog; quite a few examples have been written there.

Guillaume

PS : Thanks Thomas for the draft you made about this article ;)

Inbound calls management with Ruby Dial plans in My SIP Switch

Wednesday, May 21st, 2008

Ruby dial plan within My SIP Switch can really prove to be powerful. They turned My SIP Switch into an easily customizable webPBX. This article aims at providing an introduction (definitely not an overview!) to inbound call management using MySIPSwitch Ruby Dial Plan.

Since programming is involved, non-technical users will need to start with the basis and then do some tweaking. More technically advanced people can really create powerful rules to block calls, to forward calls, to create some backup routes in case of call failure (busy, not available, …) with timers….

A good place to get information on ruby dial plans is the sticky thread on My SIP Switch forum: Ruby Dial Plans.

In this article, I’ll focus on the dial plan side and I consider that some SIP providers have been set up to receive calls.


1. Structure of the Ruby Dial Plan

Here is an example of empty Ruby dial plan:

#Ruby
sys.Log(”call from #{req.Header.From.FromURI.ToString()} to #{req.URI.User}.”)
if sys.In then
# Inbound rules here
else
# Outbound rules here
end

The 1st thing to mention is that the Ruby dial plan must start by “#Ruby”, that allows My SIP Switch to know that your dial plan is using Ruby and not the old syntax.

Then, the command sys.Log(”bla”), allows to leave some logs (ie: some debugging or informative comments) that will be displayed on the monitoring page. That’s a handy tool to use when testing.

sys.In (or sys.Out) are Booleans (true or false) that tell you if the present call is an incoming call or an outgoing call.

Note that any line starting by # will be considered as a comment and therefore won’t be interpreted.


2. Example of Inbound call management

Here is a simple example with some comment afterwards:

1) # INBOUND CALLS
2) if sys.In then
3) sys.Log(”Inbound call from : #{req.Header.From.FromURI.User.ToString()}”)
4)
5) inboundnb = req.Header.From.FromURI.User
6)
7) case inboundnb
8 ) when /^0034/ then sys.Dial(”0039051xxxxxx@provider1″)
9) when /^0123456789/ then sys.Dial(”300@blueface”)
10) when /^0987654321/ then sys.Dial(”00393xxxxxx@provider2″)
11) else sys.Dial(”#{sys.Username}@local”)
12) end
13)
14) # OUTBOUND CALLS
15) else
16) # outbound call rules
1st tip: I clearly commented the 2 main sections of the dial plan: the inbound and the outbound section. Since the screen to edit the dial plan is a bit small that allows finding quicker each section.

Line 3: I added a log with the 2 parties of the inbound call. That is handy to know what’s going on when you are creating your dial plan.

Line 5: That’s a variable allocation. I store the phone number of the person calling me into the variable “inboundnb”, since using all the time “req.Header.From.FromURI.User” is not that handy.

Line 7: I created a “Switch”, it looks at the value of the variable, in this case “inboundnb”, and then will match the corresponding line. For instance:

case red
when blue then “go blue”
when green then “go green”
when red then “go red”
else “go whatever”
end

Here the “switch” will match the 3rd line. If “red” was not stated in the “when” cases, then, the last line, else, would match. Adding a default line is often useful!
Don’t forget the “end” to close the switch; otherwise, you will trigger an error!

Line 8: /^0034/ will match any number starting by 0034. If someone calls me from Spain (Spain’s international prefix is 0034), I forward the call to my Italian landline since I know the call won’t be for me. The call forwarded will be billed via my provider: provider1.

Line 9: If I don’t want to talk to the owner of the phone number: 012456789, then I forward it to 300@blueface, he will hear some monkeys; more seriously, I could send a message:
sys.Respond(480, “Not available”)

Line 10: 0987654321 is that really important potential customer and I really don’t want to miss his call, so I forward it to my mobile, just in case I’m in the train or in coffee break when he calls. Note that this time I’ll use provider2 to bill that call, he has better rates than provider1 for my mobile number.

Line 11: If the dial plan didn’t match any of the previous lines, then the last one with “else” will be interpreted and in that case, the phone which will ring is the one I have registered with My SIP Switch.


3. Going further with inbound call management

- Multiple forwarding with timers :

sys.Dial(”#{sys.Username}@local”, 10)
sys.Dial(”00390xxxx@blueface”, 12)
sys.Dial(”00393xxxxx@blueface”, 15)
sys.Respond(404, “No forwards answered”)

When I receive a call, My SIP Switch will 1st try to contact the phone I have registered with it, after 10 seconds, if I don’t pick it up, then this phone stops ringing and my landline starts ringing, and if after 12 seconds, I don’t pick up the call, my mobile will ring and if I don’t reply to my mobile and then the caller will hear a recorded message saying that I’m not available.

Note that the timers start when the call is attempted, so when it starts ringing a couple of seconds can be gone already (especially for mobiles!).

Another possibility is to make 2 phones ring at the same time :
sys.Dial(”#{sys.Username}@local&mycolleaguenumber@blueface”)

Both phone will start ringing at the same time and the 1st to pick up will get the call and the other one will stop ringing.

- Availability checker

The following piece of code can prove to be very handy:

sys.Log(”isavailable=#{sys.IsAvailable().ToString()}.”)
if sys.IsAvailable()
sys.Dial(”#{sys.Username}@local”)
else
sys.Dial(”mymobile@provider”)
end

sys.IsAvailable is a Boolean : true or false. If true, then my phone will ring, if not (my internet connection died, I ran out of battery, …) then I forward the call to my mobile.

- Time management

Here is a quick example, showing that you can also route the call depending the on the time of day:

t = Time.now
timezoneoffset = -1
if (t.hour >= 18+timezoneoffset )
sys.Dial(”…”)
else
sys.Dial(”…”)
end

First : Note that Time.Now will be at GMT since My SIP Switch server is based in Dublin

One trick to cope with that is to set a variable with the time different between your zone and GMT, for instance, I’m based in Italy (GMT+1), so I need to substract 1 from the time I want my rule to match.

Here is a good page with references about Time management in Ruby : http://www.ruby-doc.org/core/classes/Time.html

That’s it for the introduction!
If you want to go further you can combine bits from the different examples I explained here and/or discuss this on My SIP Switch’s forum with other users.