如何在 C# 中创建多级 IVR(交互式语音应答)菜单系统
本文逐步介绍了如何在 C# 中创建一个高级多级 VoIP IVR,以扩展您的基本菜单系统并改进您的整体客户服务。
引言
IVR(交互式语音应答)菜单系统提供了在电话上自动化业务流程的灵活性。由于可定制的菜单和各种呼叫路由选项,客户查询可以得到有效和轻松的管理。客户无需与呼叫中心座席交谈即可通过 IVR 访问各种服务。由于它有助于提高座席的工作效率,IVR 菜单系统也可以帮助改进整个呼叫中心。
背景
几周前,我创建了一个基本的 IVR 菜单系统,可以无需人工干预即可接收和管理来电。它已经扩展了盲转功能。考虑到在当今的商业世界中,更高级的多级 IVR 被广泛使用,我改进了我的 IVR 解决方案。
“多级”意味着呼叫者可以通过使用 DTMF 信令导航到多个菜单级别——如**图 1** 所示。在这篇简短的文章中,我将解释如何开发一个高级多级 IVR。
图 1:多级 IVR 工作原理的简单示例
先决条件
我的解决方案基于我之前创建的 IVR 项目。本文没有描述第一步(例如在 IDE 中进行设置或实现必要的类),因为所有必需的初始任务都已在我之前的教程中详细解释。可以在以下链接中找到
如何在 C# 中构建一个基本的 IVR(交互式语音应答)菜单系统以改进您的呼叫中心:https://codeproject.org.cn/Articles/746512/How-to-build-a-basic-IVR-Interactive-Voice-Respons
- 我用 C# 构建了我的 IVR 应用程序,所以您需要一个支持此编程语言的 IDE(集成开发环境),例如 Microsoft Visual Studio。
- 您的 PC 上还需要安装 .NET Framework。
- 由于我的 IVR 系统基于 VoIP 技术,您需要在 IDE 的引用中添加一些 VoIP 组件,以便以最简单的方式定义 IVR 的默认行为。由于我一直使用 Ozeki VoIP SIP SDK 进行 VoIP 开发,我使用了此 SDK 中预编写的 VoIP 组件。因此,它也需要安装在您的 PC 上。
编写代码
在我的项目中使用了 4 个类:Softphone.cs
、CallHandler.cs
、Program.cs
、NewCallHandler.cs
。要实现多级 IVR 解决方案,首先您需要在 CallHandler
类中进行一些修改。让我们逐步看看您需要做什么。
CallHandler.cs 类中的修改
在我的基本 IVR 系统中,我只构建了一个菜单级别,客户在按 3 后可以转接到实时座席。由于我将开发一个多级系统,现在不需要实现最后一部分(“盲转的实现”),因为您稍后(在最后一个菜单级别)将需要此功能。如果您已经创建了该盲转功能,请打开 CallHandler.cs
类并删除 call_DtmfReceived()
方法的盲转部分。
要创建多级系统,您的 IVR 必须能够将呼叫者导航到下一个菜单级别。为此,您需要创建一个方法——它被称为 LowerMenu()
。它将管理菜单级别之间的导航(代码示例 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;
}
}
代码示例 1: call_DtmfReceived() 方法中的 LowerMenu()
方法
在 LowerMenu()
方法中,首先您需要取消订阅所有当前事件(呼叫的 CallStateChanged
和 DtmfReceived
事件;greetingMessageTimer
的 Elapsed
事件)。
现在您需要创建一个名为 NewCallHandler
的新类。它将管理较低菜单级别中的呼叫。
完成此步骤后,返回 LowerMenu()
方法并从新类创建一个对象。使用此对象调用两个方法(BlindTransferNumber()
、Start()
)并订阅其 Completed
事件。(您可以在下面的“实现 NewCallHandler.cs 类”部分阅读这些方法的实现(代码示例 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();
}
代码示例 2: LowerMenu() 方法的实现
当呼叫者按下 DTMF 按钮以完成较低菜单并返回主级别时,newCallHandler_Completed()
方法可用于重新订阅事件并启动问候消息(代码示例 3)。
void newCallHandler_Completed(object sender, EventArgs e)
{
call.CallStateChanged +=call_CallStateChanged;
call.DtmfReceived +=call_DtmfReceived;
StartGreetingMessage();
greetingMessageTimer.Start();
}
代码示例 3:newCallHandler_Completed() 方法
实现 NewCallHandler.cs 类
让我们看看如何完成 NewCallHandler.cs
类。
如果呼叫者进入此子菜单(在我的示例中通过按 3),他/她将通过扬声器听到问候消息和可选的菜单项。在我的示例中,呼叫者可以选择两个选项:转接到指定的电话号码或返回主菜单。
call_DtmfReceived()
方法(代码示例 4)可用于处理呼叫者在第二级菜单中的选择。如果呼叫者按下 1,系统会将呼叫转接到预定义的电话号码。为了能够将呼叫者导航回主菜单,您需要创建并调用一个方法。它被称为 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;
}
}
代码示例 4: call_DtmfReceived() 方法
在此项目中,当呼叫者按下 2 时可以使用 Return()
方法。此操作表示他/她想返回主菜单。在这种情况下,需要取消订阅 call_DtmfReceived()
方法,处置当前处理程序,关闭 greetingMessageTimer
并调用 Completed
事件(代码示例 5)。
private void Return()
{
call.DtmfReceived -= call_DtmfReceived;
DisposeCurrentHandler();
greetingMessageTimer.Close();
var Handler = Completed;
if (Handler != null)
Handler(this, EventArgs.Empty);
}
代码示例 5:Return() 方法
要处理呼叫的变化,可以使用 call_CallStateChanged()
方法。如果呼叫者按下 1(即选择盲转选项),呼叫状态将变为“转接中”,系统需要处置当前处理程序并停止 greetingMessageNumber
。当呼叫状态再次变为“通话中”时,IVR 会重新启动此计时器(代码示例 6)。
void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
{
if (e.Item == CallState.InCall) greetingMessageTimer.Start();
if (e.Item == CallState.Transferring) DisposeCurrentHandler(); greetingMessageTimer.Stop();
}
代码示例 6:call_CallStateChanged() 方法
摘要
总而言之,如果您使用预先编写的 VoIP 组件,构建和改进 IVR 会非常容易和快速。处理大量并发呼叫——尤其是在大型公司中——对于能够以最高水平满足客户需求至关重要。多级 IVR 菜单系统可以管理大量的并发呼叫,同时自动化许多呼叫中心任务。由于盲转功能,客户可以轻松自动地转接到实时座席。
参考文献
有用的资源(初始开发任务)
- 此 IVR 改进基于我之前创建的 IVR 项目。要完成与 IVR 开发相关的初始任务,请阅读以下文章
如何在 C# 中构建一个基本的 IVR(交互式语音应答)菜单系统以改进您的呼叫中心:https://codeproject.org.cn/Articles/746512/How-to-build-a-basic-IVR-Interactive-Voice-Respons
理论背景
- 关于 IVR 菜单系统: https://en.wikipedia.org/wiki/Ivr
- 关于 DTMF 信令: https://en.wikipedia.org/wiki/Dtmf
- 关于 IVR 开发:http://www.voip-sip-sdk.com/p_410-interactive-voice-response-voip.html
- 关于呼叫转接: https://en.wikipedia.org/wiki/Call_transfer
- 关于呼叫中心: https://en.wikipedia.org/wiki/Call_center
下载必要的软件
- 下载 Microsoft Visual Studio: http://www.microsoft.com/hu-hu/download/visualstudio.aspx?q=visual+studio
- 下载 .NET Framework: http://www.microsoft.com/hu-hu/download/details.aspx?id=30653
- 下载 VoIP SIP SDK: http://voip-sip-sdk.com/p_21-download-ozeki-voip-sip-sdk-voip.html