freeswitch 呼叫中心,freeswitch 呼叫流程

FresSWITCH呼叫中心同步报工号对于坐席,可以更敏捷感知客户来电,对呼叫中心运营有一定的帮助。坐席电话长通免除了客服代表每次来电都要摘机的操作,对20秒接通率(考核指标不一定是20秒)有一定的帮助。

FresSWITCH呼叫中心模块实现报工号比较简单,客户和坐席同步报工号则稍微麻烦一点,其实也就是使用的app不一样而已。实现的思路,坐席联系方式不直接进分机,而是进到一个拨号计划,再在拨号计划内执行lua脚本。坐席长通是通过设置坐席通话完毕后挂起坐席电话,后来的电话直接查找sip_dialogs表获取uuid,直接将客户电话与坐席电话进行uuid桥接方式实现。

具体配置如下:


1、坐席配置“联系”方式设置(callcenter配置)

将坐席的联系方式由直呼分机号改为呼出到号码,并将坐席工号以SIP消息头携带,配置示例如下:

contact="[sip_h_X-cc_agent='12345',leg_timeout=10]sofia/internal/90021002@10.203.196.232"

说明:9002是用来判断接入报工号拨号的计划的字冠,1002是坐席分机号,10.203.196.232是FreeSWITCH的域名。


2、dialplan设置

在conf/dialplan/public.xml最上边添加一个拨号计划,示例如下:

  <extension name="agent_access">    <condition field="destination_number" expression="^9002(\d{4})$">      <action application="lua" data="play_agent_id.lua $1"/>    </condition>  </extension>

说明:在public目录下新增拨号计划貌似有问题,坐席联系方式只匹配一次拨号计划,所以这个拨号计划只能放在最顶部,建议在匹配号码前先匹配一次ACL规则。


3、lua脚本

播报工号的功能由lua脚本实现(事实上在上述拨号计划添加相应的app也可以实现),lua示例如下:

local custormer_session=session;local api=freeswitch.API();local dbh=freeswitch.Dbh(freeswitch.getGlobalVariable("dsn"));local file_ringback='/usr/local/freeswitch/sounds/music/default/8000/danza-espanola-op-37-h-142-xii-arabesca.wav'custormer_session:setVariable("ringback", file_ringback);custormer_session:preAnswer();local caller_id_number=custormer_session:getVariable("caller_id_number")local agent_phone=argv[1];local v_uuid_sql="select t.uuid from sip_dialogs t where t.sip_from_user=\'"..agent_phone.."\' and t.sip_from_host=\'"..freeswitch.getGlobalVariable("domain").."\';";local query_uuid=assert(dbh:query(v_uuid_sql, function(row)        agent_uuid=row["uuid"];end))local agent_id=nilif (custormer_session:getVariable("sip_h_X-cc_agent")) then        agent_id=custormer_session:getVariable("sip_h_X-cc_agent");else        agent_id=agent_phoneendif (agent_uuid==nil) then        local agent_session=freeswitch.Session("{ignore_early_media=true,origination_caller_id_name=SF-TECH.Call-Center,origination_caller_id_number='9001',leg=2}user/"..agent_id.."@10.203.196.232");        agent_session:setAutoHangup(false);        agent_session:setVariable("park_after_bridge","true")        agent_session:setVariable("hangup_after_bridge","false")        if (agent_session:ready()) then                custormer_session:answer();                custormer_session:execute("sched_broadcast","+1 playback::ivr/ivr-customer_service.wav both");                custormer_session:execute("sched_broadcast","+2 say::\'zh name_spelled pronounced "..agent_id.."\' both");                api:execute("sleep", "800")                freeswitch.bridge(custormer_session,agent_session)        endelse        custormer_session:answer();        local custormer_uuid=custormer_session:getVariable("uuid");        custormer_session:execute("sched_broadcast","+1 playback::ivr/ivr-customer_service.wav both");        custormer_session:execute("sched_broadcast","+2 say::\'zh name_spelled pronounced "..agent_id.."\' both");        api:execute("sleep", "800")        api:execute("uuid_bridge",custormer_uuid.." "..agent_uuid)end

说明:这里播放的工号为坐席分机号,如果你的坐席工号为纯数字也可以取cc-agent变量值来播报,如果配合TTS甚至可以播放客服代表的姓名,计划广播的时延按实际播报的语音长度进行调整。我这里已经加了中文语音和一些自己录的音,如果你没有加这些语音,那么这个脚本会报错。


本方案优势:除了实现同步报工号和坐席长通,还可将IVR、call_center模块、坐席录音模块分离,具体实现方式这里不作讨论;

本方案局限性:因转坐席电话时发起了“呼出”的操作,因此通道变量无法直接获取,只能通过SIP消息传递、数据库或其他中间件来存取,个人倾向于SIP消息传递,毕竟传一个SIP消息头,整个系统的运算量相比其他方式要小得多。