[Ed. 13 Aug 2008 - Small change to sys.Respond]
[Ed. 16 Aug 2008 - Added new method sys.GTalk]
[Ed: 21 Sep 2008 - Clarified dial string for sys.Dial command]
As of 25 Mar 2008 dial plans can now be written as Ruby (http://www.ruby-doc.org/docs/ProgrammingRuby/) scripts. Using a script instead of a single command allows much greater flexibility in power for processing calls.
To specify a dialplan should be interpreted as Ruby the dialplan must have #Ruby on the first line. An example of a minimalist Ruby dialplan is:
#Ruby
sys.Dial("blueface")
All the standard Ruby expressions and constructs are available for use and in addition two locally scoped variables are added to all dialplan scripts for each call processed:
- sys (stands for System) and contains some helper methods and dialplan commands.
- req (stands for Request) and contains the received INVITE request,
Reference:
sys.Callback(string dest1, string dest2) - Initiates a call to dest1 and if successful then calls dest2 and bridges the calls together. The dest1 and dest2 parameters are SIP Provider constructs.
Code: Select all
# Ruby dialplan example for sys.Callback
sys.Log("call received uri=#{req.URI.User}")
sys.Callback("012345@blueface", "023456@voipstunt")
Code: Select all
# Ruby dialplan example for sys.Dial
sys.Log("call received uri=#{req.URI.User}")
sys.Dial("blueface") if req.URI.User.StartsWith("3")
sys.Respond(404, "No dialplan match")
[dst@]provider[, true]
dst - is the optional call destination. If not specified the call destination of the initiating request will be used. The dst can also make use of the initiating request value by using ${dst} or ${dst:n} to trim n characters from the start.
provider - must be a provider name or a valid DNS host name.
true - if present inidcates a trace is required.
Examples:
Code: Select all
sys.Dial("provider1")
sys.Dial("1234@provider1")
sys.Dial("1234@provider1, true")
sys.Dial("${dst:1}@provider1")
Code: Select all
# Ruby dialplan example for sys.Dial
sys.Log("call received uri=#{req.URI.User}")
sys.Dial("provider1", 10)
sys.Dial("provider2", 15)
sys.Dial("provider3", 10)
sys.Respond(404, "No forwards answered")
Examples of correctly formatted numbers:
0.0.0.0.2.4.2.5.1.3.5.3.enum.org
35315242000.enum.org
+35315242000.enum.org
003531524200.enum.org
Examples of incorrectly formatted numbers:
35315242000
0.0.0.0.2.4.2.5.1.3.5.3
Code: Select all
# Ruby dialplan example for sys.ENUMLookup
enumuri = sys.ENUMLookup("35315242000.mysipswitch.com")
if enumuri != nil
sys.Dial(enumuri)
else
sys.Respond(404, "ENUM lookup failed")
end
Code: Select all
#Ruby dialplan example for sys.GetBindings()
if sys.IsAvailable() then
bindings = sys.GetBindings()
bindings.each { |binding| sys.Log("#{binding.ContactSIPURI.Host}.") }
end
Code: Select all
#Ruby dialplan example for sys.GTalk.
sys.GTalk("joe.bloggs", "password", "jane.doe", "Hello World!")
sys.GTalk("joe.bloggs", "password", "jane.doe", "#{req.URI.User}")
bool sys.In and bool sys.Out - Can be used to determine whether a call being processed by the dialplan is an outgoing or incoming call. An outgoing call is one you as the owner of the dialplan are placing. An incoming call is one being received from an external caller to you.
Code: Select all
#Ruby dialplan example for sys.In and sys.Out
if sys.Out then # sys.In can also be used in the same manner.
sys.Log("Outgoing call from user domain=#{sys.FromDomain}.")
sys.Dial("blueface")
else
sys.Log("Incoming call to domain=#{sys.ToDomain}.")
if sys.IsAvailable() then
sys.Log("#{sys.Username} is online.")
sys.Dial("local")
else
sys.Log("#{sys.Username} is not online.")
sys.Respond(480, "#{sys.Username} Not online")
end
end
bool sys.IsAvailable() - Is used to check whether the dial plan owner's account has a SIP account online. The function returns true if there is a current binding and false otherwise.
Code: Select all
#Ruby dialplan example for sys.IsAvailable()
sys.Log("call received uri=#{req.URI.User} from #{req.Header.From.FromURI.User}")
sys.Log("isavailable=#{sys.IsAvailable().ToString()}.")
if sys.IsAvailable()
sys.Dial("me@local")
else
sys.Dial("mymobile@provider")
end
Code: Select all
# Ruby dialplan example for sys.Log
sys.Log("Log message from Ruby dialplan.")
sys.Log("Incoming call for uri=#{req.URI.User}.").
Code: Select all
# Ruby dialplan example for sys.Respond
sys.Respond(404, "No dialplan match")
sys.Trace = true|false - Activates or deactivates tracing of dial plan calls. The trace will be sent to the email address registered on the owning sipsiwtch account once the call is answered or is unsuccessful.
Code: Select all
# Ruby dialplan example to turn tracing on
sys.Trace = true
req.URI - The SIP URI for the incoming request.
req.URI.User - The user portion of the request URI this is the value used in the non-Ruby dial plans as ${EXTEN} or ${dst}.
req.URI.Host - The host portion of the request URI.
req.Header - The SIP Headers for the incoming request.
req.Header.From - The SIP From header for the incoming request.
req.Header.From.FromURI - The URI portion of the From header.
req.Header.From.FromName - The name portion of the From header.
req.Header.To - The SIP To header for the incoming request.
req.Header.To.ToURI - The URI portion of the To header.
req.Header.To.ToName - The name portion of the To header.
req.Header.Contact[0] - The first Contact header in the incoming Request.
req.Header.Contact[0].ContactURI - The URI of the first Contact header.
req.Header.Contact[0].ContactName - The Name of the first Contact header.
req.Header.CSeq
req.Header.CallId
etc.
A special case is req.Header.From which is what most SIP Providers will use to set custom callerid's if they support it. Unfortunately the From header is also normally used to identify who you are so changing it can affect your ability to authenticate your call.
It is possible to customise the From header on a forwarded call.
Code: Select all
req.Header.From.FromURI.User = "01234567"
req.Header.from.FromURI.Host = "mydomain.com"
req.Header.From.FromName = "Joe Bloggs"
From: "Joe Bloggs" <sip:01234567@mydomain.com>
The field that is generally used for authentication is req.Header.From.FromURI.User so be aware your calls could fail if it is modified.
Some of the above fields are strings and can be used directly in log messages. If you get an error logging an object add ToString() at the end of it. For example:
sys.Log("Call received for #{req.URI.ToString()}")
An example of a Ruby dialplan that is equivalent to the non-Ruby approach is:
#Ruby
sys.Log("call received uri=#{req.URI.ToString()}")
case req.URI.User
when "123" then sys.Dial("fwd")
when "456" then sys.Dial("voipstunt")
else sys.Dial("blueface")
end
The documentation above is far from complete but should serve to help get anyone interested started.
Note of warning: The Ruby engine in use by the sipswitch is a development project called IronRuby (http://www.ironruby.net/) and there are almost certainly going to be issues with the implementation at this early stage.
Second note of warning: The following strings are not permitted anywhere in a Ruby dialplan: require, include, system, :: and `. This is to prevent scripts from executing privileged operations on the sipswitch server.
Regards,
Aaron