freeswitch呼叫中心队列callcenter动态加载

引言

mod_callcenter呼叫中心队列模块,能够提供丰富的坐席管理和呼叫功能。以上功能都可以通过配置callcenter.conf.xml来完成,我们可以选择静态配置也可以通过mod_xml_curl模块动态加载callcenter.conf.xml来实现,本章讲解动态加载配置文件

本人已经使用freeswitch开发出整体的核心产品,提供功能接口,通过接口即可实现呼叫中心业务功能,无需关心freeswitch开发。功能包括IVR动态导航、坐席动态添加、动态拨号计划、坐席登入、登出、置忙、空闲、通话、呼叫转移、呼叫保持、墙插、强拆、通话记录上传、弹屏上传等功能,只需要调用http接口即可实现呼叫中心业务,有意合作可邮箱联系mokeily99@126.com

原理

通过mod_xml_curl模块配置远端服务地址,远端服务返回对应的callcenter.conf.xml文件内容

步骤

1、开启mod_callcenter功能

1.1加载mod_callcenter模块

mod_callcenter模块并不是默认编译安装的,需要将modules.xml中的mod_callcenter选项打开

然后源码目录执行

make mod_callcenter-install

在autoload_configs/modules.conf.xml中去掉<load module="mod_callcenter"/>的注释,重启freeswitch(或者load mod_callcenter)

1.2呼叫中心队列文件callcenter.conf.xml

autoload_configs/callcenter.conf.xml即为队列文件,如下:

<configuration name="callcenter.conf" description="CallCenter">
  <settings>
    <param name="odbc-dsn" value="MYSQLTP:root:xxxxxx"/>
    <!--<param name="dbname" value="/dev/shm/callcenter.db"/>-->
  </settings>

  <queues>

    <queue name="support@default">
          <param name="strategy" value="random"/>
          <param name="moh-sound" value="/usr/local/freeswitch/scripts/sound/waiting.wav"/>
          <param name="record-template" value="/root/web-app/record/apache-tomcat-8.5.76/webapps/record/${strftime(%Y-%m-%d-%H-%M-%S)}_${caller_id_number}_${destination_number}.wav"/>
          <param name="time-base-score" value="system"/>
          <param name="max-wait-time" value="40"/><!--最大等待时间(超过时间未被接通将退出callcenter)0为禁用-->
          <param name="max-wait-time-with-no-agent" value="2"/><!--无成员(没有成员的状态是available)等待超时时间: 超出时间电话会退出callcenter 0为禁用-->
          <param name="max-wait-time-with-no-agent-time-reached" value="1"/><!--如果有电话有因为(max-wait-time-with-no-agent)的原因退出队列, 队列将在延迟一定时间不允许新的电话呼入到队列-->
          <param name="tier-rules-apply" value="false"/>
          <param name="tier-rule-wait-second" value="300"/>
          <param name="tier-rule-wait-multiply-level" value="true"/>
          <param name="tier-rule-no-agent-no-wait" value="true"/>
          <!--<param name="discard-abandoned-after" value="10"/>-->
         <!--<param name="abandoned-resume-allowed" value="true"/>-->

    </queue>

  </queues>

<!-- WARNING: Configuration of XML Agents will be updated into the DB upon restart. -->
<!-- WARNING: Configuration of XML Tiers will reset the level and position if those were supplied. -->
<!-- WARNING: Agents and Tiers XML config shouldn't be used in a multi FS shared DB setup (Not currently supported anyway) -->
  <agents>
    <!--<agent name="1000@default" type="callback" contact="[call_timeout=10]user/1000@default" status="Available" max-no-answer="3" wrap-up-time="10" reject-delay-time="10" busy-delay-time="60" />-->
        <agent name="1001@default" type="callback" contact="[call_timeout=10]user/1001" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="5" busy-delay-time="2" />
        <agent name="1002@default" type="callback" contact="[call_timeout=10]user/1002" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="5" busy-delay-time="2" />

        <agent name="1004@default" type="callback" contact="[call_timeout=10]user/1004" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="5" busy-delay-time="2" />
  </agents>
  <tiers>
    <!-- If no level or position is provided, they will default to 1.  You should do this to keep db value on restart. -->
    <!-- <tier agent="1000@default" queue="support@default" level="1" position="1"/> -->
        <tier agent="1001@default" queue="support@default" state="Ready" level="1" position="1"/>
        <tier agent="1002@default" queue="support@default" state="Ready" level="1" position="1"/>
        <!--<tier agent="1004@default" queue="support@default" state="Ready" level="1" position="1"/>-->
  </tiers>

</configuration>

注:文件中采用了数据入库操作<param name="odbc-dsn" value="MYSQLTP:root:xxxxxx"/>参照Freeswitch替换sqlLit改为mysql,同时记录通话话单_freeswitch mysql_十年一梦惊觉醒的博客-CSDN博客2配置mysqlDSN目标数据库需要创建坐席表,以及包含坐席号和密码字段。

1.3动态加载callcenter.conf.xml

静态的队列文件局限性较大,每次增加队列都需要手动修改xml。动态加载通过mod_xml_curl模块加载xml文件即可实现callcenter.conf.xml的动态加载,原理就是mod_xml_curl模块会通过xml_curl.conf.xml文件中配置的远程服务,加载相应的xml配置文件内容,远程服务只需要动态拼装所需的xml内容即可

1.3.1加载mod_xml_curl模块

已加载该模块的无需操作该步骤。

进入项目源码编辑文件modules.conf,取消掉xml_int/mod_xml_curl的注释

make mod_xml_curl-install

修改autoload_configs/modules.conf.xml文件,去掉<load module="mod_xml_curl"/>的注释,重启freeswitch(或者load mod_xml_curl)

1.3.2编辑xml_curl.conf.xml文件

xml_curl.conf.xml是动态加载xml配置文件,理论上他能加载freeswitch的所有xml文件。标红处为修改内容,通过configuration方式加载callcenter.conf.xml文件,注:configuration理论上可以加载所有xml配置文件,web接口处可以打印下入参,根据不同请求返回不同xml配置文件内容。

<configuration name="xml_curl.conf" description="cURL XML Gateway">
  <bindings>
    <binding name="example">
      <!-- Allow to bind on a particular IP for requests sent -->
      <!--<param name="bind-local" value="$${local_ip_v4}" />-->
      <!-- The url to a gateway cgi that can generate xml similar to
           what's in this file only on-the-fly (leave it commented if you dont
           need it) -->
      <!-- one or more |-delim of configuration|directory|dialplan -->
      <!-- <param name="gateway-url" value="http://www.freeswitch.org/gateway.xml" bindings="dialplan"/> -->
      <!-- set this to provide authentication credentials to the server -->
      <!--<param name="gateway-credentials" value="muser:mypass"/>-->
      <!--<param name="auth-scheme" value="basic"/>-->

      <!-- optional: this will enable the CA root certificate check by libcurl to
           verify that the certificate was issued by a major Certificate Authority.
           note: default value is disabled. only enable if you want this! -->
      <!--<param name="enable-cacert-check" value="true"/>-->
      <!-- optional: verify that the server is actually the one listed in the cert -->
      <!-- <param name="enable-ssl-verifyhost" value="true"/> -->

      <!-- optional: these options can be used to specify custom SSL certificates
           to use for HTTPS communications. Either use both options or neither.
           Specify your public key with 'ssl-cert-path' and the private key with
           'ssl-key-path'. If your private key has a password, specify it with
           'ssl-key-password'. -->
      <!-- <param name="ssl-cert-path" value="$${certs_dir}/public_key.pem"/> -->
      <!-- <param name="ssl-key-path" value="$${certs_dir}/private_key.pem"/> -->
      <!-- <param name="ssl-key-password" value="MyPrivateKeyPassword"/> -->
      <!-- optional timeout -->
      <!-- <param name="timeout" value="10"/> -->

      <!-- optional: use a custom CA certificate in PEM format to verify the peer
           with. This is useful if you are acting as your own certificate authority.
           note: only makes sense if used in combination with "enable-cacert-check." -->
      <!-- <param name="ssl-cacert-file" value="$${certs_dir}/cacert.pem"/> -->

      <!-- optional: specify the SSL version to force HTTPS to use. Valid options are
           "SSLv3" and "TLSv1". Otherwise libcurl will auto-negotiate the version. -->
      <!-- <param name="ssl-version" value="TLSv1"/> -->

      <!-- optional: enables cookies and stores them in the specified file. -->
      <!-- <param name="cookie-file" value="$${temp_dir}/cookie-mod_xml_curl.txt"/> -->

      <!-- one or more of these imply you want to pick the exact variables that are transmitted -->
      <!--<param name="enable-post-var" value="Unique-ID"/>-->
    </binding>

        <binding name="configuration">
      <param name="gateway-url" value="http://127.0.0.1:18892/fs-core/pbxInter/initCallcenterInfo" bindings="configuration"/>
    </binding>
  </bindings>
</configuration>

<binding name="configuration">

      <param name="gateway-url" value="http://127.0.0.1:18892/fs-core/pbxInter/initCallcenterInfo" bindings="configuration"/>

    </binding>

为修改内容

1.3.2创建远程服务

以上配置中http://127.0.0.1:18892/fs-core/pbxInter/initCallcenterInfo即为需要创建的服务地址。服务代码参照:

@RequestMapping(value = "/initCallcenterInfo")
	@ResponseBody
	public String initCallcenterInfo(HttpServletRequest req, HttpServletResponse res) {

		String keyValue = req.getParameter("key_value");
		String profile = req.getParameter("profile");
		String code = req.getParameter("code");

		logger.info("获取callcenter xml-请求参数:code=" + code + ",keyValue=" + keyValue + ",profile=" + profile);
		StringBuffer sb = new StringBuffer();
		try {

			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
			sb.append("   <document type=\"freeswitch/xml\">\n");
			sb.append("	 	<section name=\"configuration\">\n");
			sb.append("	   		<configuration name=\"callcenter.conf\" description=\"CallCenter\">\n");
			sb.append("		  	<settings>\n");
			sb.append("			<param name=\"odbc-dsn\" value=\"MYSQLTP:root:AA39noway\"/>\n");
			sb.append("		  </settings>\n");

			sb.append("		  <queues>\n");
			List<Map<String, Object>> queueList = queueService.getQueueList(null);
			for (Map<String, Object> queue : queueList) {
				sb.append("			<queue name=\"" + queue.get("queue_acc") + "@default\">\n");
				sb.append("			  <param name=\"strategy\" value=\"" + queue.get("queue_strategy") + "\"/>\n");
				sb.append(
						"			  <param name=\"moh-sound\" value=\"/usr/local/freeswitch/scripts/sound/waiting.wav\"/>\n");
				sb.append(
						"			  <param name=\"record-template\" value=\"/root/web-app/record/apache-tomcat-8.5.76/webapps/record/${uuid}.wav\"/>\n");
				sb.append("			  <param name=\"time-base-score\" value=\"system\"/>\n");
				sb.append("			  <param name=\"max-wait-time\" value=\"20\"/>\n");
				sb.append("			  <param name=\"max-wait-time-with-no-agent\" value=\"2\"/>\n");
				sb.append("			  <param name=\"max-wait-time-with-no-agent-time-reached\" value=\"1\"/>\n");
				sb.append("			  <param name=\"tier-rules-apply\" value=\"false\"/>\n");
				sb.append("			  <param name=\"tier-rule-wait-second\" value=\"300\"/>\n");
				sb.append("			  <param name=\"tier-rule-wait-multiply-level\" value=\"true\"/>\n");
				sb.append("			  <param name=\"tier-rule-no-agent-no-wait\" value=\"true\"/>\n");
				sb.append("			</queue>\n");
			}
			sb.append("		  </queues>\n");

			sb.append("		  <agents>\n");
			List<Map<String, Object>> seatList = seatService.getSeatList(null);
			for (Map<String, Object> seat : seatList) {
				sb.append("			<agent name=\"" + seat.get("seat_no")
						+ "@default\" type=\"callback\" contact=\"[call_timeout=10]user/" + seat.get("seat_no")
						+ "\" status=\"Available\" max-no-answer=\"100\" wrap-up-time=\"2\" reject-delay-time=\"20\" busy-delay-time=\"10\" no-answer-delay-time=\"10\" />\n");
			}
			sb.append("		  </agents>\n");

			sb.append("		  <tiers>\n");
			List<Map<String, Object>> tierList = seatService.getTierList(null);
			for (Map<String, Object> tier : tierList) {
				sb.append("			<tier agent=\"" + tier.get("seat_no") + "@default\" queue=\""
						+ tier.get("queue_acc") + "@default\" state=\"Ready\" level=\"1\" position=\"1\"/>\n");
			}
			sb.append("		  </tiers>\n");
			sb.append("		</configuration>\n");
			sb.append("	 </section>\n");
			sb.append(" </document>\n");

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("获取callcenter xml-返回参数:" + JSONObject.fromObject(result).toString());
		return sb.toString();
	}

        服务返回xml参照以下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
   <document type="freeswitch/xml">
	 	<section name="configuration">
	   		<configuration name="callcenter.conf" description="CallCenter">
		  	<settings>
			<param name="odbc-dsn" value="MYSQLTP:root:AA39noway"/>
		  </settings>
		  <queues>
			<queue name="support@default">
			  <param name="strategy" value="random"/>
			  <param name="moh-sound" value="/usr/local/freeswitch/scripts/sound/waiting.wav"/>
			  <param name="record-template" value="/root/web-app/record/apache-tomcat-8.5.76/webapps/record/${uuid}.wav"/>
			  <param name="time-base-score" value="system"/>
			  <param name="max-wait-time" value="20"/>
			  <param name="max-wait-time-with-no-agent" value="2"/>
			  <param name="max-wait-time-with-no-agent-time-reached" value="1"/>
			  <param name="tier-rules-apply" value="false"/>
			  <param name="tier-rule-wait-second" value="300"/>
			  <param name="tier-rule-wait-multiply-level" value="true"/>
			  <param name="tier-rule-no-agent-no-wait" value="true"/>
			</queue>
		  </queues>
		  <agents>
			<agent name="1006@default" type="callback" contact="[call_timeout=10]user/1006" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="1003@default" type="callback" contact="[call_timeout=10]user/1003" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2007@default" type="callback" contact="[call_timeout=10]user/2007" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2008@default" type="callback" contact="[call_timeout=10]user/2008" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="6666@default" type="callback" contact="[call_timeout=10]user/6666" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="1001@default" type="callback" contact="[call_timeout=10]user/1001" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="8888@default" type="callback" contact="[call_timeout=10]user/8888" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="1004@default" type="callback" contact="[call_timeout=10]user/1004" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2009@default" type="callback" contact="[call_timeout=10]user/2009" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2001@default" type="callback" contact="[call_timeout=10]user/2001" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2005@default" type="callback" contact="[call_timeout=10]user/2005" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2010@default" type="callback" contact="[call_timeout=10]user/2010" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
			<agent name="2006@default" type="callback" contact="[call_timeout=10]user/2006" status="Available" max-no-answer="100" wrap-up-time="2" reject-delay-time="20" busy-delay-time="10" no-answer-delay-time="10" />
		  </agents>
		  <tiers>
			<tier agent="2006@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="1001@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="8888@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="2007@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="2010@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="1003@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="6666@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="2005@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="1006@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="2009@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="1004@default" queue="support@default" state="Ready" level="1" position="1"/>
			<tier agent="2008@default" queue="support@default" state="Ready" level="1" position="1"/>
		  </tiers>
		</configuration>
	 </section>
 </document>

启动远端服务,重启freeswitch即可动态加载callcenter。如有问题可咨询mokeily99@126.com

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十年一梦惊觉醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值