Hack Your Business, Part 2: Integrating your Phone System

Back
Peter-Christoph Haider on 09/12/2016.

One of the great things about ZeyOS is the fact that you can create your own API endpoints using iXML and Zymba. This allows you to enhance and automate a great many things for your business with only a few lines of code.

In our "Hack your business" series we want to show you a practical real-life example how you can utilize ZeyOS to digitalize your company.

In this episode, we are going to show you how you can use iXML to identify a caller based on the incoming number and display his or her name and company on the display of your phone. In this case, we are going to use a SNOM 370 VoIP phone, but you can be sure that other phone systems work with similar API interfaces.

The principal of our script looks as follows:

  1. A call comes, the phone rings
  2. The phone sends an HTTP request with the caller's number to ZeyOS
  3. ZeyOS checks if the number exists in the address book and returns the caller's name and company
  4. The phone displays the received information on the phone display

Getting started

The first point of reference to make such a system work is the API definition of the phone system. Here, we need to answer the following questions:

  1. How can we configure an URL that will be called for incoming calls?
  2. How can we pass on the phone number?
  3. What is the required result format, so that the phone can interpret and display our return values?

In case of Snom the API is pretty straightforward:

  1. URL registration: In your phone settings, you can simply configure a URL that should be called every time a call comes in. See screenshot
  2. The phone number is passed on as a URL parameter called $remote. The local extension is called $local.
  3. In order to display information on your display, we can use Snom's XML format. So a simple response would look like this:

Snom Phone Settings

Putting it all together

So let's get started and create a new service in ZeyOS. If you already have the ZeyOS SDK installed, you should do this using the SDK simply because it's more convenient. In this example, we are going to use the browser console, since we will only edit one little script.

Step 1: Create the REST service

Creating a REST service in ZeyOS is easy! Simply add a new service by typing "Remotecall" and use the rest:server command to create new rest server. In our case, we will simply call the service phoneid and add a REST endpoint /:local/:remote:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ixml SYSTEM "http://www.ixmldev.com/schema/ixml.dtd">
<ixml>
    <rest:server>
        <rest:resource method="GET" route="/:local/:remote/">
            <!-- Your code here -->
        </rest:resource>
    </rest:server>
</ixml>

The service is now available with the following URL: https://cloud.zeyos.com/<instance>/remotecall/phoneid/. We will later place this URL in the Snom phone settings.

Step 2: Identify the caller

In order to identify the caller, we are going to perform a database query and check if the number belongs to a contact. First, we will split the $remote string, since it contains the phone number and the SIP account number, separated by an @ sign.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ixml SYSTEM "http://www.ixmldev.com/schema/ixml.dtd">
<ixml>
    <rest:server>
        <rest:resource method="GET" route="/:local/:remote/">
            <split pattern="/@/" var="parts">$remote</split>
            <array:shift var="parts" var_result="number" />
            <array:shift var="parts" var_result="account" />

            <!-- Check if the number is not empty -->
            <if value1="$number">
                <break />
            </if>

            <db:select var_result="contact" type="self" limit="1">
                <db:fields>
                    <db:field>firstname</db:field>
                    <db:field>lastname</db:field>
                    <db:field>company</db:field>
                </db:fields>
                <db:table>contacts</db:table>
                <db:search query="$number">
                    <db:searchfield>phone</db:searchfield>
                    <db:searchfield>phone2</db:searchfield>
                    <db:searchfield>cell</db:searchfield>
                </db:search>
                <db:is field="visibility">0</db:is>
                <db:orderby>
                    <db:orderfield type="desc">type</db:orderfield>
                </db:orderby>
            </db:select>

            <!-- Stop, if no contact could be identified -->
            <if value1="$contact.lastname">
                <break />
            </if>
        </rest:resource>
    </rest:server>
</ixml>

Step 3: Build the result

If the identification was successful, we simply insert our database values into the XML envelope and output the result.

And that's it! Include the URL in your phone settings and give it a try:

Snom Phone Settings

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ixml SYSTEM "http://www.ixmldev.com/schema/ixml.dtd">
<ixml>
    <rest:server>
        <rest:resource method="GET" route="/:local/:remote/">
            <split pattern="/@/" var="parts">$remote</split>
            <array:shift var="parts" var_result="number" />
            <array:shift var="parts" var_result="account" />

            <!-- Check if the number is not empty -->
            <if value1="$number">
                <break />
            </if>

            <db:select var_result="contact" type="self" limit="1">
                <db:fields>
                    <db:field>firstname</db:field>
                    <db:field>lastname</db:field>
                    <db:field>company</db:field>
                </db:fields>
                <db:table>contacts</db:table>
                <db:search query="$number">
                    <db:searchfield>phone</db:searchfield>
                    <db:searchfield>phone2</db:searchfield>
                    <db:searchfield>cell</db:searchfield>
                </db:search>
                <db:is field="visibility">0</db:is>
                <db:orderby>
                    <db:orderfield type="desc">type</db:orderfield>
                </db:orderby>
            </db:select>

            <!-- Stop, if no contact could be identified -->
            <if value1="$contact.lastname">
                <break />
            </if>

            <!-- Initialize the name and company values -->
            <set var="name">$contact.lastname</set>
            <if value1="$contact.firstname" func="!=">
                <concat var="name">, $contact.firstname</concat>
            </if>
            <if value1="$contact.company">
                <set var="contact.company">-</set>
            </if>

            <!-- Return the XML code for Snom -->
            <output><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
            <SnomIPPhoneText>
             <Title>$name</Title>
             <Prompt>Incoming call</Prompt>
             <Text>
               Company: $contact.company<br/>
               Number:  $number<br/>
               Account: $account
             </Text>
            </SnomIPPhoneText>]]></output>
        </rest:resource>
    </rest:server>
</ixml>

And here's the result:

Snom Phone Settings

Where to go from here?

Now that our script is working, you have several options to enhance the existing script. For instance, you could add a service that ensures that all phone numbers in your system match the format given by Snom. You could also display additional features on your display, such as the date of the last call you had, etc.

I hope this short example could illustrate how easy it is to integrate other systems with ZeyOS and how fast you can increase productivity with such simple tweaks! If you need any help during your customization process, simply contact us