Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Excerpt

This example written in Ruby allows users to manage VoipNow accounts and fetch call statistics.

Table of Contents
typelist

Note
titleThe code is on GitHub

Download here. If you want to improve this example, do not hesitate to contribute. We welcome Pull Requests.

How To Install It

System Requirements

To be able to use the SystemAPI Ruby Tool, you must meet the following requirements:

  • Download Ruby for Linux or Windows.
  • Download SOAP4R, a Ruby library that provides access the Web Services via SOAP.

Setup

STEP 1: Start by downloading the example files:

Code Block
git clone https://github.com/4psa/systemapi-example-ruby.git

STEP 2: Install GCC for Linux.

Note

You may skip this step for Windows, since Ruby for Windows comes with an installation package.

GCC should come with your operating system. In case it doesn't, simply run one of the commands below.

For CentOS/RHEL:

Code Block
yum install gcc

For Debian/Ubuntu:

Code Block
apt-get install gcc

STEP 3: Install Ruby. You should use Ruby 2.3.

On Linux:

Once the download is complete, extract the archive to a temporary folder, go to that folder and run:

Code Block
./configure
make
make install

On Windows:

Run the installer associate the.rb files with Ruby, and add Ruby to PATH.

STEP 4: To install SOAP4R, you need rubygems. If rubygems was not installed with Ruby, you can download it from here. Once the download is complete, extract the archive to a temporary folder, go to that folder and run:

Code Block
ruby setup.rb

STEP 5:  Then install SOAP4R, a Ruby library that allows you to access Web Services via SOAP. Here is the command line for it:

Code Block
gem install soap4r
Note

Although the latest versions of Ruby come with SOAP4R in their standard library, it is highly recommended to use the latest gem.

Note

SOAP4R is not updated anymore. To ensure that SOAP4R works with the latest versions of Ruby, you must go to <PATH_TO_RUBY_GEMS>/soap and patch the following files:

./lib/xsd/charset.rb

./lib/xsd/codegen/gensupport.rb

./bin/wsdl2ruby.rb

./lib/xsd/xmlparser.rb.

The patches are in the same repository as the example files.

STEP 6: Install logger-application, a Ruby library which replaces Logger for the latest Ruby versions.

Code Block
gem install logger-application

STEP 7: Create a directory for 4PSA VoipNow schemas on your local disk (i.e. C:\schema or /home/your_user/schema).

STEP 8: Run the script that generates the Ruby library from the schema.

On Linux:

Code Block
none
none
cd /home/your_user/schema
./wsdl2ruby.sh . <IP_ADDRESS

On Windows:

Code Block
none
none
cd C:\schema
wsdl2ruby.bat . <IP_ADDRESS>
Code Block
titleExample
cd C:\schema
wsdl2ruby.bat . voipnow2demo.4psa.com

This utility will generate four files inside the C:\schema folder.

Code Block
none
none
VoipNowService.rb
VoipNowServiceMappingRegistry.rb
AccountPortClient.rb
VoipNowServiceDriver.rb

The main class used by your client program is VoipNowServiceDriver.rb.

Note

If you are using self-signed certificates, the script will fail.

In this case, you must go to <PATH_TO_RUBY_GEMS>/httpclient/lib/httpclient/ssl_socket.rb and change the value of variable verify_mode into OpenSSL::SSL::VERIFY_NONE

Note

You must move the files generated by the script to one of the Ruby folders $LOAD_PATH

STEP 9: At this point, you can start writing your applications for your VoipNow server.

How To Use It

Authentication

Whatever you intend to do in the application, you will need to create an object.

STEP 1: If you want to add a new service provider, you should instantiate a new object as follows:

Code Block
ruby
ruby
driver = ServiceProviderInterface.new

STEP 2: For the SystemAPI message, you will need a new custom header. So, you will create a new class called AuthHeader that you need to customize for each authentication method. 

To add the new header to the recently created driver object, please write the following code line:

Code Block
ruby
ruby
driver.headerhandler << AuthHeader.new

Here is how you can create the AuthHeader class. The OAuth protocol requires that you provide the access token generated for your application. In short, the code should look something like this:

Code Block
ruby
ruby
# Custom header for authentication
class AuthHeader < SOAP::Header::SimpleHandler

  # the namespace for the header data
  NAMESPACE = 'http://4psa.com/HeaderData.xsd/3.5.0'

  # Authentication data
  ACCESS_TOKEN = 'CHANGEME'

  #initializes an instance of this class
  def initialize()
    super(XSD::QName.new(NAMESPACE, 'userCredentials'))
  end

  #sets the user credentials with the authentication data
  def on_simple_outbound
    {"userCredentials" => {"accessToken" => ACCESS_TOKEN}}
  end

end

Examples

Add a Service Provider

In DemoAddServiceProvider.rb, you have an example on how to add to add a new service provider. The script also fetches the list of charging plans you can choose from and use for the new service provider:

Add Other Account Types

If you want to add other account types (organizations, users or extensions), simply tweak the previous Service Provider example as detailed below.

STEP 1: Depending on the type of account you want to add, you need to change the driver object type from ServiceProviderInterface to:

  • OrganizationInterface
  • UserInterface
  • ExtensionInterface

 It should look like this:

Code Block
languageruby
driver = OrganizationInterface.new

STEP 2: Adjust the message of the request and ensure it contains the parentIDDepending on the account type you want to add, this ID can be:  

  • The service provider that owns the organization (when adding a new organization)
  • The organization that owns the user (when adding a new user) 
  • The user that owns the extension (when adding a new extension) 
  • The extension for which the report is generated (when getting call costs)

Here is the code for picking a random parent from the list of available accounts.

Code Block
languageruby
# We need a parent service provider for the new organization, so we make a request to
# fetch all the service providers.
driver = ServiceProviderInterface.new
driver.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_NONE
# Add custom header
driver.headerhandler << AuthHeader.new
#the getServiceProviders message
messagePart = GetServiceProviders.new
# Log for SystemAPI request and response
driver.wiredump_file_base = "log"
#send the SystemAPI message
serviceProviders = driver.getServiceProviders(messagePart)
serviceProviderID = nil
if serviceProviders.serviceProvider != nil
	if serviceProviders.serviceProvider.length != 0
		randServiceProvider = serviceProviders.serviceProvider[rand(serviceProviders.serviceProvider.length)]
		if randServiceProvider.iD != nil
			serviceProviderID = randServiceProvider.iD
			if randServiceProvider.name != nil
				puts "Using parent service provider " + randServiceProvider.name + "."
			else
				puts "Using parent service provider with id " + serviceProviderID + "."
			end
		end
	end
end
if serviceProviderID == nil
	puts "No service providers found on the server. Can not add an organization."
	exit
end

Here is the code for the AddOrganization request.

Code Block
languageruby
#the AddOrganization message
messagePart = AddOrganization.new
# Fill in Organization data
messagePart.name = 'OrgRuby' + rand(1000).to_s
messagePart.login = 'OrgRuby' + rand(1000).to_s
messagePart.firstName = 'FirstnameRuby' + rand(1000).to_s
messagePart.lastName = 'LastnameRuby' + rand(1000).to_s
messagePart.email = 'Email' + rand(1000).to_s + '@example.com'
messagePart.password = SecureRandom.hex(16)
messagePart.country = 'us'
messagePart.company = 'test_company'
messagePart.parentID = serviceProviderID
if chargingPlanID != nil
	messagePart.chargingPlanID = chargingPlanID
end

STEP 3:  At this point, you need to call the proper method. To add an organization, instead of:

Code Block
languageruby
puts driver.addServiceProvider(messagePart)

Run the following:

Code Block
languageruby
puts driver.addOrganization(messagePart)

Do the same for the other two account types, User and Extension. 

CallCosts

The DEMO version also provides a CallCosts request example. Here is the code.

 

Except where otherwise noted, content in this space is licensed under a Creative Commons Attribution 4.0 International.