Ruby VoIP developers 101

Part 2: Ruby example on recording VoIP calls, call routing

The Ozeki Phone System gives you the opportunity to use its special features. If you have any problem how to log calls, record or route them, do not hesitate to read this guide. All the answers can be found below, and far more information about the mentioned advanced features.

Part 1: Ruby example on sending SMS, making VoIP calls
Part 3: Ruby connection with gem library (SMS)
Part 4: Ruby connection with gem library (Calls)
Part 5: Ruby SDK Commands

Overview

This page assumes that you already have some basic knowledge in Ruby programming language. If you don't have these skills, then you should check out our basic example site at Ruby basic example.

1. Call state change with logging

First you should create a controller, which handles call state changes, connects to a MySQL database, and inserts the call state change informations into a table. With the rails g controller Callstatelog command you could create your controller, and add the following code to the newly created callstatelog_controller.rb.

  protect_from_forgery except: :call_state_changed

  require 'mysql2'

  # http://localhost:3000/callstatelog/call_state_changed
  def call_state_changed

      config = YAML::load_file("config/database.yml")["development"]
      config["host"] = config["hostname"]
      con = Mysql2::Client.new(config)

      con.query("CREATE DATABASE IF NOT EXISTS Ozeki_CallStateChanges;")
      con.query("CREATE TABLE IF NOT EXISTS Ozeki_CallStateChanges.Call_States
        (id INT NOT NULL AUTO_INCREMENT, call_id VARCHAR(10), caller_id VARCHAR(30),
        caller VARCHAR(30), callee VARCHAR(30), call_state VARCHAR(255), PRIMARY KEY (id));")

      notification_name = params[:NotificationName] == nil ? "" : params[:NotificationName]
      call_id = params[:CallId] == nil ? "" : params[:CallId]
      caller_id = params[:CallerId] == nil ? 0 : params[:CallerId]
      caller = params[:Caller] == nil ? "" : params[:Caller]
      callee = params[:Callee] == nil ? "" : params[:Callee]
      call_state = params[:CallState] == nil ? "" : params[:CallState]
  
      con.query("INSERT INTO Ozeki_CallStateChanges.Call_States (call_id, caller_id, caller, callee, call_state)
        VALUES ('" + call_id + "', '" + caller_id + "', '" + caller + "', '" + callee + "', '" + call_state + "');")
      
    rescue Mysql2::Error => e
      puts e.errno
      puts e.error
    ensure
      con.close if con
    
  end
					

Code example 1 - Call state change logging

In the Ozeki Phone System, under the HTTP API Configure menu item, select the General tab and set up the Call changed URL (In this case it will be http://localhost:3000/callstatelog/call_state_changed).

2. Call recording

First you should create a controller, which returns an OzML response, with the Record command, it specifies, that the calls should be recorded. The Record command has the finishedUrl attribute, which will tell the system which URL should be called after the call has finished. First we execute the rails g controller Recording command you could create your controller, and add the following code to the newly created recording_controller.rb.

  # http://localhost:3000/recording/record
  def record

    render :xml => '<?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Record finishedUrl="http://localhost:3000/recording/recording_finished" format="mp3"/>
    </Response>'

  end
				

Code example 2 - Return an OzML response to record a call

After the call finished, it will call the below function, which will store some information in a MySQL table.

  protect_from_forgery except: :recording_finished
  
  require 'mysql2'
  
  # http://localhost:3000/recording/recording_finished
  def recording_finished

      config = YAML::load_file("config/database.yml")["development"]
      config["host"] = config["hostname"]
      con = Mysql2::Client.new(config)

      con.query("CREATE DATABASE IF NOT EXISTS Ozeki_CallRecordings;")
      con.query("CREATE TABLE IF NOT EXISTS Ozeki_CallRecordings.Call_Recordings
        (call_id VARCHAR(10), success BIT, duration INT, caller VARCHAR(30), callee VARCHAR(30), record_url VARCHAR(255), notification_name VARCHAR(30));")

      call_id = params[:CallId] == nil ? "" : params[:CallId]
      success = params[:Success] == nil ? false : params[:Success]
      duration = params[:Duration] == nil ? 0 : params[:Duration]
      caller = params[:Caller] == nil ? "" : params[:Caller]
      callee = params[:Callee] == nil ? "" : params[:Callee]
      record_url = params[:RecordURL] == nil ? "" : params[:RecordURL]
      notification_name = params[:NotificationName] == nil ? "" : params[:NotificationName]
      
      con.query("INSERT INTO Ozeki_CallRecordings.Call_Recordings (call_id, success, duration, caller, callee, record_url, notification_name)
        VALUES ('" + call_id + "', " + success + ", " + duration + ", '" + params[:Caller] + "', '" + params[:Callee] + "'
        , '" + params[:RecordURL] + "', '" + notification_name + "');")
      
    rescue Mysql2::Error => e
      puts e.errno
      puts e.error
    ensure
      con.close if con
    
  end
				

Code example 3 - Insert call recording details into MySQL database

In the Ozeki Phone System, under the HTTP API Configure menu item, select the General tab and set up the Call changed URL (In this case it will be http://localhost:3000/recording/record).

3. Call routing

Besides Dial Plan, it is possible to give a Ruby method, so you can decide which extension answers the call when forwarding your calls. If you did not forward the call, it will be handle by the rules of Dial Plan. You can enter into the Route interception URL field the path of your method (e.g. http://yoursite.com/RouteCalls/RouteCall) in the Productivity menu's, HTTP API submenu.
To do this, you need to create a controller with the rails g controller Routing command, and place the following code into the created controller.

  protect_from_forgery except: :rule

  # http://localhost:3000/routing/rule
  def rule

    notification_name = params[:NotificationName] == nil ? "" : params[:NotificationName]
    caller_id = params[:CallerID] == nil ? "" : params[:CallerID]
    original_dialed_number = params[:OriginalDialedNumber] == nil ? 0 : params[:OriginalDialedNumber]
    last_dialed_number = params[:LastDialedNumber] == nil ? "" : params[:LastDialedNumber]
    last_called_extension = params[:LastCalledExtension] == nil ? "" : params[:LastCalledExtension]
    last_call_state = params[:LastCallState] == nil ? "" : params[:LastCallState]
    caller_extension = params[:CallerExtension] == nil ? "" : params[:CallerExtension]

    if ((last_call_state == 'NoAnswer') || (last_call_state == 'Busy')) 
      render :xml => '<?xml version="1.0" encoding="UTF-8"?>
      <Response>
        <Route Destination="2000"/>
      </Response>'
    elsif (original_dialed_number == '1000')
      render :xml => '<?xml version="1.0" encoding="UTF-8"?>
      <Response>
        <Route RingTime="5" Destination="9998"/>
      </Response>'
    else
      render :xml => ''
    end

  end
				

Code example 4 - Return an OzML response in order to route a call

In the Ozeki Phone System, under the HTTP API Configure menu item, select the General tab and set up the Route interception URL (In this case it will be http://localhost:3000/routing/rule).

Read more about Route command or other OzML commands.

Part 3: Ruby connection with gem library (SMS)

If you have any questions or need assistance, please do not hesitate to contact us at info@ozekiphone.com

More information