回拨或“提高客户忠诚度”

星号,一组操作员(3-5人),工作量大(平均等待时间> 2分钟)

任务是让具有特定地理位置的订户有机会不等到话务员有空之后,并按0听到“谢谢您的电话。 我们一定会给您回电“,通过智能回叫断开连接并平静地等待来自运营商的电话,无论是普通人还是普通人

建立表格
创建表asterisk.callback(
id int(11)非空AUTO_INCREMENT,
dt时间戳记DEFAULT CURRENT_TIMESTAMP,
cid varchar(32)默认为空,
dst varchar(32)DEFAULT NULL,
status smallint(6)非空默认值0,
tot_calls int(11)非空默认值0,
last_call时间戳记DEFAULT'0000-00-00 00:00:00',
compl_dt timestamp DEFAULT'0000-00-00 00:00:00',
uniqueid varchar(32)DEFAULT NULL,
队列varchar(255)DEFAULT NULL,
主键(ID)

引擎= INNODB

创建表asterisk.callback_log(
id int(11)非空AUTO_INCREMENT,
callback_id int(11)非空,
dt时间戳记DEFAULT CURRENT_TIMESTAMP开启UPDATE CURRENT_TIMESTAMP,
状态varchar(32)DEFAULT NULL,
参数varchar(2048)DEFAULT NULL,
主键(id),
CONSTRAINT callback_log_fk1外键(callback_id)
参考asterisk.callback(id)在删除级联上在更新级联上

引擎= INNODB

编辑extensions.conf

 exten => 88142590067,s,1
     same => n,GotoIf($ [“ $ {CALLERID(num):0:4}” =“ 8814”]?额外); 如果号码是本地号码,则允许回叫
 ....您可以在此处插入更多支票...
    相同=> n,转到(调用)
     same => n(额外),NoOp(允许$ {CALLERID(num)}的回调)
    相同=> n,设置(ALLOW_CALLBACK = 1)
    相同=> n,设置(CALLBACK_QUEUE =运算符)
    相同=> n,背景(vse /按0进行回调)

     same => n(通话),NoOp(向操作员询问。GROUP_COUNT = $ {GROUP_COUNT(操作员)})
    相同=> n,队列(运算符,tThH)
    相同=> n,挂断

包括=> main_menu_press

 [main_menu_press]
 exten => 0.1,NoOp('-------------------- $ {CALLERID(num)}按下按钮$ {EXTEN}。ALLOW_CALLBACK = $ {ALLOW_CALLBACK} ')
     same => n,GotoIf($ [$ {ALLOW_CALLBACK} = 1]?callback,s,1:i,1)

 [回叫]
 exten => s,1,NoOp(回叫)
     same => n,播放(感谢您的通话&vse / my-vam-perezvonim)
    相同=> n,挂断

 exten => h,1,agi(callback.php,gen,0,$ {CALLBACK_QUEUE})

 [回呼]
 exten => _X。,1,NoOp(尝试拨入队列($ {CALLBACK_QUEUE})并回调到$ {CALLBACK_NUM})
    相同=> n,设置(__ DST =“?”)
     same => n,Set(CALLERID(num)= $ {CALLBACK_NUM})
    相同=> n(通话),队列($ {CALLBACK_QUEUE},tT)
    相同=> n,NoOp(回呼QUEUESTATUS = $ {QUEUESTATUS})

 [macro-queue-answ]; 接线员回答后,我们到达了这里。 
 exten => s,1,NoOp(队列成员回答uniq = $ {UNIQUEID} cid = $ {CALLERID(num)} chan = $ {CHANNEL} callback_id = $ {CALLBACK_ID} callback_num = $ {CALLBACK_NU
    同样=> n,GotoIf($ [“ $ {CALLBACK_ID} x” =“ x”]?跳过)
    相同=> n,设置(DST = $ {CHANNEL})
    相同=> n,设置(CALLERID(num)= 067)
     same => n,播放(私有尝试); 播放操作员“等待连接”
    相同=> n,agi(callback.php,队列应答,$ {CALLBACK_ID},$ {CHANNEL},$ {UNIQUEID})
    相同=> n,拨号(本地/ $ {CALLBACK_NUM} @from_office_new)
    相同=> n,NoOp([宏队列应答]拨号超时)
    相同=> n(跳过),NoOp()

 exten => h,1,NoOp([宏队列应答]拨号挂断)
     same => n,GotoIf($ [“ $ {CALLBACK_ID} x” =“ x”]?结束)
    相同=> n,NoOp(拨号状态= $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
    相同=> n,否(my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})
    相同=> n,agi(callback.php,hangup-queue-answing,$ {CALLBACK_ID},$ {CHANNEL},$ {UNIQUEID})
    相同=> n(结束),NoOp

 [回拨完成]
 exten => s,1,NoOp(回调完成。CALLBACK_ID= $ {CALLBACK_ID},uniq = $ {UNIQUEID},dst = $ {DST} chan = $ {CHANNEL})
    相同=> n,NoOp(拨号状态= $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
    相同=> n,否(my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})


Queues.conf文件
 [经营者]
     ringinuse =否
    策略=内存
    音乐=默认
    成员=> SIP / 321
    成员=> SIP / 322
    成员=> SIP / 323
    成员=> SIP / 324
    成员=> SIP / 325
    成员=>代理/ 1
    成员=>代理/ 2
    成员=>代理/ 3
    成员=>代理/ 4
    成员=>代理/ 5
    上下文= main_menu_press
    超时= 0
    公告位置=是
    宣布频率= 60
    定期播报频率= 30
     queue-youarenext =队列-youarenext
     membermacro =队列-answ


好吧,实际上是脚本(检测到PHP)

config.php
<?php ob_implicit_flush(true); set_time_limit(6); date_default_timezone_set('Europe/Moscow'); mysql_connect("localhost","asterisk","***") or die('Mysql connect error'); mysql_select_db("asterisk"); // ******************************* function genCallbackFile($id,$cid,$queue) { $fname='/var/spool/asterisk/outgoing/callback-'.$id; if (file_exists($fname)) return; $callfile="Channel: Local/".$cid."@do-callback\n". "WaitTime: 60\n". "MaxRetries: 1\n"."RetryTime: 120\n". "Context: callback-complete\n". "Extension: s\n". "Set: __CALLBACK_ID=$id\n". "Set: __CALLBACK_QUEUE=$queue\n". "Set: __CALLBACK_NUM=$cid\n"; $fp=fopen($fname,'w+');fputs($fp,$callfile);fclose($fp); } ?> 


callback.php
 #!/usr/bin/php <? $arg=$_SERVER["argv"]; $a=$arg[1]; $id=abs($arg[2]); include('/var/lib/asterisk/agi-bin/config.php'); $in = fopen("php://stdin","r"); $stdlog = fopen("/var/log/asterisk/callback.log", "a+"); // toggle debugging output (more verbose) $debug = false; // parse agi headers into array while ($env=read()) { $s = split(": ",$env); $agi[str_replace("agi_","",$s[0])] = trim($s[1]); if (($env == "") || ($env == "\n")) { break; } } // main program ************************ $dt=date('dmY H:i:s'); $cid=$agi[callerid]; switch ($a) { case 'cid-answ' : { // -    $stmt='select * from callback where id='.$id; $result=mysql_query($stmt); $row=mysql_fetch_object($result); $cid=$row->cid; $stmt="select * from callback where id=$id or (dt>(now()-interval 24 hour) and cid='$cid' and STATUS<>2)"; $result=mysql_query($stmt); while ($row=mysql_fetch_object($result)) { $id=$row->id; $stmt="update callback set status=2,compl_dt=now() where id=$id"; $result=mysql_query($stmt); rename('/var/spool/asterisk/outgoing/callback-'.$id,'/tmp/callback-'.$id); } break; } case 'queue-answ' : { //     .       $dst=$arg[3]; $stmt=sprintf('update callback set status=1,last_call=now(),tot_calls=tot_calls+1,dst="%s",uniqueid="%s" where id=%d",$dst,$agi[uniqueid],$id); $result=mysql_query($stmt); break; } case 'complete' : { //  ,        ,   callfile  $id=abs($arg[2]); $stmt='select * from callback where id='.$id; $result=mysql_query($stmt); $row=mysql_fetch_object($result); if ($row->status!=2) genCallBackFile($id,$row->cid,$row->queue); break; } case 'gen': { //        $qname=trim($arg[3]); if (!$qname) $qname='operators'; //        0, ,    .      $stmt=sprintf('select * from callback where cid="%s" and queue="%s" status<>2 and dt>now()-interval 24 hour',$cid,$qname); $result=mysql_query($stmt); if (!$row=mysql_fetch_object($result)) { $stmt="insert into callback (cid,queue) values ('$cid','$qname')"; $result=mysql_query($stmt); $id=mysql_insert_id(); fputs($stdlog,"$dt|$stmt\n"); } else { $log_status='cid '.$cid.' already in spool '.$qname; } genCallBackFile($id,$cid,$qname); break; } } $stmt=sprintf('insert into callback_log (callback_id,status) values (%d,"%s -> %s")',$id,$a,$log_status); $result=mysql_query($stmt); $log_id=mysql_insert_id(); // clean up file handlers etc. fclose($in); fclose($stdlog); exit; // **************************************** ?> 


然后,我们又放置了一个callback-regen.php文件,用于在上午8点至晚上8点之间每5分钟刷新一次通话记录。
每次尝试时,重复通话的时间都会增加5分钟。 在尝试模拟运算符10次后,停止
 #!/usr/bin/php <? include('/var/lib/asterisk/agi-bin/config.php'); $stmt='select * from callback where status<>2 and dt>now()-interval 24 hour and tot_calls<=10 '. ' and last_call<now()-interval tot_calls*5 minute '. ' group by cid,queue'; $result=mysql_query($stmt); while ($row=mysql_fetch_object($result)) { genCallBackFile($row->id,$row->cid,$row->queue); } // **************************************** ?> 

Source: https://habr.com/ru/post/zh-CN471500/


All Articles