Introduction
An IVR (Interactive Voice Response) menu
system offers the flexibility to automate the business processes on the
phone. Due to the customizable menus and the variety of call routing options,
customer queries can be managed effectively and easily. Customers can access
various services over the IVR without speaking with the call center agents. As it
helps in improving the agent’s productivity, an IVR menu system can help in
improving the whole call center as well.
Background
A couple of weeks ago I have created a
basic IVR menu system that can receive and manage the incoming calls without
any human intervention. It has been extended with blind transfer functionality.
Concerning to the fact, that in today’s business world the more advanced
multi-level IVRs are commonly used, I improved my IVR solution.
’Multi-level’
means that the caller can be navigated through more menu levels by using DTMF
signalling – as it can be seen in Figure 1. In this brief article I am going to
explain how to develop an advanced multi-level IVR.
Figure 1: A simple example on how a multi-level IVR works
Prerequisites
My solution is based on my previously
created IVR project. The first steps (such as settings in your IDE or the
implementation the necessary classes) have not been described in this tip, because
all the required initial tasks have been explained in details in my previous
tutorial. It can be found at the following link:
How to build a basic IVR (Interactive
Voice Response) menu system in C# to improve your call center: http://www.codeproject.com/Articles/746512/How-to-build-a-basic-IVR-Interactive-Voice-Respons
- I have built my IVR application in C#,
so you need an IDE (Integrated Development Environment) supporting this
programming language, such as Microsoft Visual Studio.
- .NET Framework installed on your PC is
also needed.
- As my IVR system is based on VoIP
technology, you need to add some VoIP components to the references in your IDE
in order to define the default behaviour of the IVR in the simplest way. Since
I have been using Ozeki VoIP SIP SDK for VoIP developments, I used the
prewritten VoIP components of this SDK. So it also need to be installed on your
PC.
Writing the code
In my project 4 classes have been used:
Softphone.cs
, CallHandler.cs
, Program.cs
, NewCallHandler.cs
. To implement the
multi-level IVR solution first you need to conduct some modifications in the
CallHandler
class. Let’s see step-by-step what you need to do.
Modifications in the CallHandler.cs
class
In my basic IVR system I have built only
one menu level in which the customer can be transferred to a live agent after
pressing 3. Since I am going to develop a multi-level system, now it is not
required to implement this last section ('The implementation of the blind
transfer'), because you will need this feature later (in the last menu level).
If you have already created that blind transfer functionality, open the
CallHandler.cs
class and delete the Blind transfer section of the call_DtmfReceived()
method.
To create a multi-level system, your IVR
has to be able to navigate the caller to the next menu level. For this purpose
you need to create a method – it is called LowerMenu()
. It will manage the
navigation through the menu levels (Code example 1).
void call_DtmfReceived(object sender, VoIPEventArgs<DtmfInfo> e)
{
DisposeCurrentHandler();
switch (e.Item.Signal.Signal)
{
case 0: break;
case 1: TextToSpeech("Product XY has been designed for those software developers who especially interested in VoIP developments. If you prefer .NET programming languages, you might be interested in Product XY."); break;
case 2: MP3ToSpeaker(); break;
case 3: LowerMenu(); break;
}
}
Code example 1: LowerMenu() method in the
call_DfmfReceived() method
In the LowerMenu()
method, first you
need to unsubscribe from all of your actual events (CallStateChanged
and
DtmfReceived
events of the call; Elapsed
event of the greetingMessageTimer
).
Now you need to create a new class that
is called NewCallHandler
. It will manage the calls in the lower menu level.
Having done this step, go back to the
LowerManu()
method and create an object from the new class. Call two methods
(BlindTransferNumber()
, Start()
) with this object and subscribe on the
Completed
event of that. (You can read about the implementation of these
methods below in the ’Implementing the NewCallHandler.cs class’ section (Code example
2)).
private void LowerMenu()
{
call.CallStateChanged -= call_CallStateChanged;
call.DtmfReceived -= call_DtmfReceived;
greetingMessageTimer.Elapsed -= greetingMessageTimer_Elapsed;
NewCallHandler newCallHandler = new NewCallHandler(call);
newCallHandler.BlindTransferNumber(blindTransferNumber);
newCallHandler.Completed += newCallHandler_Completed;
newCallHandler.Start();
}
Code example 2: The implementation of the LowerMenu() method
The
newCallHandler_Completed()
method can be used to subscribe back to the events
and start the greeting message when the caller press a DTMF button to finish
and complete the lower menu and return to the main level (Code example 3).
void newCallHandler_Completed(object sender, EventArgs e)
{
call.CallStateChanged +=call_CallStateChanged;
call.DtmfReceived +=call_DtmfReceived;
StartGreetingMessage();
greetingMessageTimer.Start();
}
Code example 3: The
newCallHandler_Completed() method
Implementing the NewCallHandler.cs class
Let’s see how to complete the
NewCallHandler.cs
class.
If the caller enters into this submenu –
in my example by pressing 3 – he/she will hear a greeting message and the
selectable menu items through the speaker. In my example the caller can choose from
two options: transferring to a specified phone number or returning to the main
menu.
The call_DtmfReceived()
method (Code
example 4) can be used to handle the caller’s choice in the second menu level.
If the caller presses 1, the system will transfer the call to a predefined phone
number. In order to be able to navigate the caller back to the main manu, you
need to create and also call a method a method. It is called Return()
.
void call_DtmfReceived(object sender, VoIPEventArgs<DtmfInfo> e)
{
DisposeCurrentHandler();
switch (e.Item.Signal.Signal)
{
case 1:
{
if (blindTransferNumber == "0")
{
TextToSpeech("You did not add any number for blind transferring!");
break;
}
else
{
call.BlindTransfer(blindTransferNumber);
break;
}
}
case 2: Return(); break;
}
}
Code example 4: The call_DtmfReceived()
method
In this project, the Return()
menthod can be
used when the caller presses 2. This action indicates that he/she would like to
return to the main menu. In this case it is necessary to unsubscribe from the
call_DtmfReceived()
method, dispose the current handler, close the
greetingMessageTimer
and invoke the Completed
event (Code example 5).
private void Return()
{
call.DtmfReceived -= call_DtmfReceived;
DisposeCurrentHandler();
greetingMessageTimer.Close();
var Handler = Completed;
if (Handler != null)
Handler(this, EventArgs.Empty);
}
Code
example 5: The Return() method
To handle the changes of the call, the
call_CallStateChanged()
method can be used.
If the caller presses 1 – that is selects the blind transferring option
– the call state changes to ’Transferring’ and the system need to dispose the
current handler and stop the greetingMessageNumber
. When the call state will be
’InCall’ again, the IVR restarts this timer (Code example 6).
void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
{
if (e.Item == CallState.InCall) greetingMessageTimer.Start();
if (e.Item == CallState.Transferring) DisposeCurrentHandler(); greetingMessageTimer.Stop();
}
Code example 6: The call_CallStateChanged()
method
Summary
To
sum it up, building and improving an IVR can be quite easy and fast if you use
previously written VoIP components. Handling a huge amount of simultaneous
calls – especially among large companies – can be crucial in order to be able
to serve your customers’ needs in the highest possible level. A multi-level IVR
menu system can manage numerous simultaneous calls while automating many call
center tasks. Due to the blind transferring functionality the customer can be
transferred to a live agent easily and automatically.
References
Useful source (initial development tasks):
Theoretical background:
Download the necessary software: