Ozeki Phone System 10

Greet Caller by Name

It is time to learn how to manage your address book to greet the caller. When your installed API Extension gets a call, it will forward the Incoming call URL to your application. To manage your address book, use a sample associative array (see the example) or operate more complex ways (e.g. files or databases).

For using this feature, first login and connect to the API Extension. Wait for an Incoming call, and when it is occured, attach a TextToSpeech engine into the call and add the 'Hello CallerName' as Text. The real CallerName will be parsed out from the CallerNumber collection on the basis of the caller's phone number.

Example code coming soon...
public ActionResult GreetCaller(string notificationName, string callLegID, string caller, string apiExtension)
	IDictionary<string, string> phoneBook = new Dictionary<string, string>();
	phoneBook["+12345671"] = "John";
	phoneBook["1001"] = "Kevin";
	phoneBook["+12345675"] = "Jack";

	var callerName = "Sir or Madame";
	if (phoneBook.ContainsKey(caller))
		callerName = phoneBook[caller];

	return Content(
   "<Response>" +
	   "<Speak>Hello " + callerName + "!</Speak>" +
   "</Response>", "text/xml");
class GreetCallerController < ApplicationController
  protect_from_forgery except: :greetings

  # In routes.rb you need to set the following routing rule
  # post '/greet_caller' => 'greet_caller#index'
  def index
    phone_book =
      "+12345671" => "John",
      "1001" => "Kevin",
      "+12345675" => "Jack"
    caller_name = phone_book[params[:Caller]] || "Sir or Madam";

    render :xml => '<?xml version="1.0" encoding="UTF-8"?>
      <Speak>Hello ' + caller_name + '</Speak>

	$phoneBook = array(
	    "+12345671" => "John",
	    "1001" => "Kevin",
		"+12345675" => "Jack",);
	if (array_key_exists($_REQUEST['Caller'], $phoneBook)){ 
		$CallerName = $phoneBook[$_REQUEST['Caller']]; 
	} else {
		$CallerName = "Sir or Madame";
	print "<Response>";
		print "<Speak>Hello $CallerName!</Speak>";
	print "</Response>";
print "Content-Type: text/plain\n\n";
#You have to add the directory route of perl.exe, and print the content type

use CGI qw(:cgi-lib :standard);  # Use CGI modules that let read data passed
&ReadParse(%in); #Read in from HTTPPost parameters

%phoneBook =("+12345671", "John",
			 "+12345672", "Bill",
			 "+12345673", "Carl",
			 "1001", "Kevin",
			 "+12345675", "Jack");

my $CallerName = $phoneBook{$in{'Caller'}};

if  (!$CallerName)
	{ $CallerName = "Sir or Madam"; }

#Send response by print
'<?xml version="1.0" encoding="UTF-8"?>
	<Speak>Hello '. $CallerName .'!</Speak>
Imports System
Imports Ozeki.Media.MediaHandlers
Imports OPSSDKCommon.Model.Call
Imports OPSSDK
Imports Ozeki.VoIP

Module Module1
    Public Sub Main(args As String())
        Dim client = New OpsClient()
        AddHandler client.ErrorOccurred, Sub(sender, info)
                                         End Sub

        If Not client.Login("ozekixepbx.ip", "admin", "12345") Then
        End If

        Dim apiExtension = client.GetAPIExtension("9000")
        AddHandler apiExtension.IncomingCall, AddressOf IncomingCall
    End Sub

    Private Sub IncomingCall(sender As Object, e As VoIPEventArgs(Of ICall))
        Dim [call] = e.Item
        Dim tts = New TextToSpeech()

        AddHandler tts.Stopped, Sub(s, ev)
                                End Sub


        AddHandler [call].CallStateChanged,
                Sub(s, ev)
                    If ev.Item = CallState.Answered Then
                        Dim phoneBook = New Dictionary(Of String, String)()
                        phoneBook("+12345671") = "John"
                        phoneBook("1001") = "Kevin"
                        phoneBook("+12345675") = "Jack"

                        Dim callerName = "Sir or Madame"

                        If phoneBook.ContainsKey([call].OtherParty) Then
                            callerName = phoneBook([call].OtherParty)
                        End If

                        tts.AddAndStartText("Hello" & callerName)
                    ElseIf ev.Item.IsCallEnded() Then
                    End If
                End Sub

    End Sub
End Module
import urllib.parse
from cgi import escape

def application(environ, start_response):
    result = receiveCall(environ)

    response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(result)))]
    start_response('200 OK', response_headers)

    return [result]

def receiveCall(environ):
        length= int(environ.get('CONTENT_LENGTH', '0'))

        if(length != 0):
            body = environ['wsgi.input'].read(length)
            receivedData = urllib.parse.parse_qs(body.decode("utf-8"))
            caller = escape(receivedData['Caller'][0])

            phoneBook = {'+12345671':"John", '1001':"Kevin", '+12345675':"Jack"}
            callerName= "Sir or Madame"
            if caller in phoneBook:
                callerName= phoneBook[caller]
            return """<?xml version="1.0" encoding="UTF-8"?>
                <Speak>Hello {0}</Speak>
    except IOError:
        return ""
using System;
using System.Collections.Generic;
using OPSSDK;
using OPSSDKCommon.Model.Call;
using Ozeki.Media.MediaHandlers;
using Ozeki.VoIP;

namespace OPS_QuickStartExample_CSharp
    class Program
        static void Main(string[] args)
            var client = new OpsClient();
            client.ErrorOccurred += (sender, info) =>

            if (!client.Login("ozekixepbx.ip", "admin", "12345"))

            var apiExtension = client.GetAPIExtension("9000");
            apiExtension.IncomingCall += IncomingCall;

        private static void IncomingCall(object sender, VoIPEventArgs  e)
            var call = e.Item;
            var tts = new TextToSpeech();
            tts.Stopped += (s, ev) => call.HangUp();

            call.CallStateChanged += (s, ev) =>
                if (ev.Item == CallState.Answered)
                    var phoneBook = new Dictionary();
                    phoneBook["+12345671"] = "John";
                    phoneBook["1001"] = "Kevin";
                    phoneBook["+12345675"] = "Jack";

                    var callerName = "Sir or Madame";

                    if (phoneBook.ContainsKey(call.OtherParty))
                        callerName = phoneBook[call.OtherParty];

                    tts.AddAndStartText("Hello" + callerName);
                else if (ev.Item.IsCallEnded())

package pbxsampleapp;

import com.sun.net.httpserver.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class GreetCallerbyName 
   public static void main(String[] args)
            phoneBook = new LinkedHashMap<>();
            phoneBook.put("+12345671", "John");
            phoneBook.put("1001", "Kevin");
            phoneBook.put("+12345675", "Jack");

            System.out.println("Starting http server...");
            HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0 }), 12345), 0);
            server.createContext("/greetcallerbyname", new PbxSampleApp.PBXRequestHandler());
            System.out.println("http server running on " + server.getAddress().toString());
        catch (IOException ex) { System.out.println("Error" + ex.toString()); }
    static Map<String, String> phoneBook;

    static class PBXRequestHandler implements HttpHandler
        public void handle(HttpExchange httpExchange) throws IOException
            Map parameters = parseQuery(httpExchange.getRequestURI().getQuery());
            String callerName = "Sir or Madame";
            if (parameters.containsKey("Caller") && phoneBook.containsKey(parameters.get("Caller")) )
                callerName = phoneBook.get(parameters.get("Caller").toString()).toString();
            httpExchange.getResponseHeaders().add("Content-type", "text/xml");
            String response = "<?xml version=\"1.0\"?>"
                    + "<Response>"
                    + "<Speak>Hello " + callerName + "!</Speak>"
                    + "</Response>";
            httpExchange.sendResponseHeaders(200, response.length());
            OutputStream os = httpExchange.getResponseBody();

        private Map<String, String> parseQuery(String params) throws UnsupportedEncodingException
            Map<String, String> query_pairs = new LinkedHashMap<String, String>();
            String[] pairs = params.split("&");
            String paramname;
            String value;
            for (String pair : pairs)
                int idx = pair.indexOf("=");
                paramname = pair.substring(0, idx);
                value = pair.substring(idx + 1);
                query_pairs.put(paramname, value);
                System.out.println(String.format("%s: %s", paramname, value));
            return query_pairs;
Code example 1 - Greeting the caller by using a phonebook


  1. When your application receives a call, you will get a Request with all of the call details.
  2. Fill an associative array with telephone numbers and names.
  3. In this associative array (phonebook) we are looking for the Caller parameter of the Request.
  4. After that, send back the response OzML to the caller.
If your application gets a call from 1001 (Caller), the caller will hear the following greeting message: “Hello Kevin”. Try it out! Add your telephone number and your name to the array and call your program. You will be greeted by your name. If the phonebook does not contain the number of the caller, it just says “Sir or Madame”.

Get the OPSSDK.dll

First you need to add the OPSSDK.dll reference to your project
(You can find OPSSDK.dll at C:\Program Files\Ozeki\Ozeki Phone System\Examples\.NET API\OPSSDK.dll).

Login and connect

Create a new instance of OpsClient, and subscribe to the ErrorOccurred event. Your program will communicate with the Ozeki Phone System through this client. Try to login with the client into the running Ozeki Phone System, with the address of the server(ozekixepbx.ip) and a valid username, password combination.

If you are ready, try to get an existing API Extension, with the GetApiExtension method of the OpsClient. Get more information about about the installation of API Extension.

Further steps

When you are ready with the initial steps above, subscribe the IncomingCall event of the apiExtension. This event will be triggered every time when the selected API Extension is called. In the mentioned event handler you will see the e.Item parameter, this parameter will be the call object. This call object has a CallState property, when the CallState is Ringing subscribe the CallStateChanged and the CallErrorOccurred events of the call object and Accept the call.

The CallStateChanged event will trigger when the call is going to another state. When the CallState is Answered, you can connect the devices to the call. When the call has ended, please do not forget to disconnect all devices from the call.

When the CallState is Answered, fill an associative array with telephone numbers and names. If the associative array contains the caller number, the method will get the corresponding CallerName from this array. After that, the method will start and connect a TextToSpeech object to the call, that will read the "Hello CallerName" text to the caller. Of course the CallerName will replace to the real caller name from the associative array "phone book". You can fill this array as you wish, for example from a file, that lists all numbers and names at your company. When the TextToSpeech is finished the call will hung up.

With these steps, you learned how to receive an incoming call, and greet the caller on his/her name.

More information