分享

用Freeswitch实现IVR

 草莓加冰 2017-06-06

IVR(交互式语音响应)实际上是我们经常说的电话语音菜单。Freeswitch默认的配置包含了一个功能齐全的例子。用一个分机拨打5000,就可以听到菜单提示了。当然默认的提示是英文的,大意是说欢迎来到Freeswitch,按1进入Freeswitch会议;按2进入回音程序;按3会听到等待音乐;按4会转到Freeswitch开发者Brian WestSIP电话上;按5会听到一只猴子的尖叫;按6进入下一级菜单;按9重听;拨1000~1019之间的号码则会被转到对应分机上。

1、最简单的菜单

我们先来配置一种最简单的情形。当有电话呼入时,会播放:“您好,欢迎致电某某,请直拨分机号,查号请拨0

IVR系统默认的配置文件为conf/autoload_configs/ivr.conf.xml,它装入conf/ivr_menus/目录下的所有XML文件。系统有一个示例的IVR配置,叫demo_ivr,也就是我们刚才拨5000听到的那个。

真正的菜单配置信息放到一对<menus></menus>标签中,每一对标签就描述一个菜单。每个菜单应该有一个唯一的名字,以便在拨号计划中引用。前面讲过,被装入的XML文件最外层一般都有一对“<include>”标签,以保证XML文档的完整性。为了实现目标菜单,我们创建一个XML配置文件conf/ivr_menus/welcome.xml,内容如下:

<include>

<menus>

<menu name="welcome"

greet-long="welcome.wav"

greet-short="welcome_short.wav"

invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav" exit-sound="voicemail/vm-goodbye.wav"

timeout="15000"

max-failures="3"

max-timeouts="3"

Inter-digit-timeout=2000

digit-len="4">

 

<entry action="menu-exec-app" digits="0"

param="transfer 1000XML default" />

<entry action="menu-exec-app" digits="/^(10[01][0-9])$/" param="transfer $1 XML default" />

  </menu>

</menus>

</include>

上述配置中,首先,我们指定菜单的名字是welcome,其他各项的含义如下:

greet-long指定最开始的欢迎音,该语音文件默认的位置应该是在usr/local/freeswitch/sounds目录下。在本例子中,我们都是用相对路径。

greet-short该项指定一个简短的提示音。如果用户长时间没有按键,则应该重新提示拨号,但重新提示应该简短,比如直接说“请直拨分机号,查号请拨0”。所以,可以把这么一个声音文件录制到welcome_short.wav中。

invalid-sound如果用户按错键,则会使用该提示。

exit-sound该项指定最后菜单退出时(一般是超时没有按键)的声音,默认会提示Good Bye”。

timeout指定超时时间(毫秒),即多长时间没有收到按键就超时,播放其他提示音。

max-failures为容忍用户按键错误的次数。如果用户的按键与下面配置的正则表达式不匹配,就认为是错误的。

max-timeouts最大超时次数。

inter-digit-timeout两次按键的最大间隔(毫秒)。如用户拨分机号1001时,假设拨了10,等了3s,再按01,这是系统实际收到的号码为10,则会播放invalid-sound指定的声音文件提示错误。

   digit-len说明菜单项的长度,即最大收号位数。

该菜单中有两个菜单项(entry),第一个是在用户按0时,通过menu-exec-app执行一个APP。在此处它执行transfer,将来话转到default Dialplan中进行路由,并最终转到分机1000.

第二个菜单项中的digits正则表达式会匹配用户输入的1000~1019之间的分机,也就是转到default Dialplan中进行路由,并最终转到对应分机上。

如果来电用户按其他按键,则由于找不到匹配的菜单项进而提示错误,并提示用户重新输入。

以上设置成功后,我们就可以配置Dialplan把用户来话转接到菜单,在Dialplan中加入一个extension(注意,需要加到正确的Dialplan Context中,如果不确定,应该加到哪个Context中,在defaultpublic中都加上会比较保险):

 <extension name="incoming_call">

      <condition field="destination_number" expression="^1234$">

          <action application="answer" data=" "/>

          <action application="sleep" data="2000"/>

     <action application="ivr" data="welcome"/>

     </condition>

</extension>

其中,正则表达式^1234$”匹配1234,即如果用户拨打1234时,就会在Dialplan中路由到这里。其中有三个action,分别指定接下来要执行的动作。首先,执行answer对来话进行应答(必须先应答才能向对方播放声音);然后使用sleep暂停2s,以防止由于声音通路没建立好而丢失声音;最后执行ivr,它的参数就是我们刚刚建立的菜单项的名字welcome

1、按时间进行路由

有时候,在一些企业应用中,可能需要按时间段进行路由。例如,在上班时间路由到一个IVR,该IVR在报完欢迎语后,可以引导转到人工总机接电话;而在下班后,来电就转到另外一个IVR

按照上面功能,我们可以构造Dialplan如下:

<extension name=time_based_ivr>

<condition wday=2-6 hour=8:30-17:30>

<action application=ivr data=ivr_day/>

<anti-action application=ivr data=ivr_night/>

</condition>

</extension>

前面我们大部分以destination_number为测试条件,但在这里,我们有两个测试条件,一个是wday,一个是hour。其中,wday表示星期(星期日的值为0);hour表示工作时间。

在有呼叫到达后,如果系统时间在该条件定义的范围内,则执行后续action中定义的App。这里,它将呼叫转到工作时间应该播放的IVR(即ivr_day)。如果时间不在定义范围内,就将呼叫转到另外一个IVR(即ivr_night)。

上面的例子没有限制被叫号码,也就是说任何被叫号码都会转到IVR。所以我们要重新配置一下。

<extension name=time_based_ivr continue=true>

<condition wday=2-6 hour=8:30-17:30>

<action application=set data=ivr=ivr_day inline=true/>

<anti-action application=set data=ivr=ivr_night   inline=true/>

</condition>

</extension>

extension使用了continue=true属性。保证在Dialplan解析完此处会继续向下执行。如果当前的时间可以匹配这里的测试条件,便会执行set,并设置ivr的值为ivr_day;否则,将ivr的变量值设为ivr_night

注意:上面的actionanti-action都设置了inline属性,它的值为true表示该动作会立即生效,以便后续的Dialplan使用此处设置的ivr变量来进行条件判断。





    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多