рдХреЙрд▓рдмреИрдХ рдпрд╛ "рдЧреНрд░рд╛рд╣рдХ рдХреА рд╡рдлрд╛рджрд╛рд░реА рдмрдврд╝рд╛рдирд╛"

рдПрдХ рдмрдбрд╝рд╛ рднрд╛рд░ рдХреЗ рд╕рд╛рде рдСрдкрд░реЗрдЯрд░реЛрдВ (3-5 рд▓реЛрдЧреЛрдВ) рдХрд╛ рдПрдХ рд╕рдореВрд╣ рддрд╛рд░рд╛рдВрдХрди рдЪрд┐рд╣реНрди рд╣реИ (рдФрд╕рдд рдкреНрд░рддреАрдХреНрд╖рд╛ рд╕рдордп> 2 рдорд┐рдирдЯ)

рдпрд╣ рдХрд╛рд░реНрдп рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рднреВрдЧреЛрд▓ рд╡рд╛рд▓реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ, рдЬреЛ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдореБрдХреНрдд рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рди рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗ, рдФрд░ 0 рд╕реБрдирдХрд░ "рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж" рджрдмрд╛рдПрдВред рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рд╡рд╛рдкрд╕ рдмреБрд▓рд╛ рд▓реЗрдВрдЧреЗ тАЭ, рд╕реНрдорд╛рд░реНрдЯ рдХреЙрд▓рдмреИрдХ рджреНрд╡рд╛рд░рд╛ рдСрдкрд░реЗрдЯрд░, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдпрд╛ рдЖрдо рд▓реЛрдЧреЛрдВ рд╕реЗ рдХреЙрд▓ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдВ рдФрд░ рд╢рд╛рдВрддрд┐ рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ

рдЯреЗрдмрд▓ рдмрдирд╛рдПрдВ
рдмрдирд╛рдПрдБ рддрд╛рд▓рд┐рдХрд╛ рддрд╛рд░рд╛рдВрдХрди рдЪрд┐рд╣реНрдиред
рдЖрдИрдбреА рдЗрдВрдЯ (11) рдирд╣реАрдВ рдкреВрд░реНрдг AUTO_INCREMENT,
dt рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк DEFAULT CURRENT_TIMESTAMP,
cid varchar (32) DEFAULT NULL,
dst varchar (32) DEFAULT NULL,
рд╕реНрдЯреЗрдЯрд╕ рд╕реНрдореЙрд▓рд┐рдВрдЯрди (6) рдлреБрд▓ рдиреЙрдЯ рдбрд┐рдлреЙрд▓реНрдЯ 0,
tot_calls int (11) рд╢реВрдиреНрдп рдкреВрд░реНрдг 0 рдирд╣реАрдВ,
last_call рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк DEFAULT '0000-00-00 00:00:00',
рд╢рд┐рдХрд╛рдпрдд_рдб рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк DEFAULT '0000-00-00 00:00:00',
рдпреВрдирд┐рдХрд┐рдб рд╡рд░реНрдЪрд░ (32) DEFAULT NULL,
рдХрддрд╛рд░ рд╡рд╛рд░реНрдЪрд░ (255) DEFAULT NULL,
рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА (рдЖрдИрдбреА)
)
рдЗрдВрдЬрди = INNODB

рдмрдирд╛рдПрдБ рддрд╛рд▓рд┐рдХрд╛ рддрд╛рд░рд╛рдВрдХрди рдЪрд┐рд╣реНрдиред
рдЖрдИрдбреА рдЗрдВрдЯ (11) рдирд╣реАрдВ рдкреВрд░реНрдг AUTO_INCREMENT,
callback_id int (11) рдкреВрд░реНрдг рдирд╣реАрдВ,
dt рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк DEFAULT CURRENT_TIMESTAMP on UPDATE CURRENT_TIMESTAMP,
рд╕реНрдЯреЗрдЯрд╕ рд╡рд░реНрдЪрд░ (32) DEFAULT NULL,
рдкрд░рдо рд╡рд░реНрдЪрд░ (2048) DEFAULT NULL,
рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА (рдЖрдИрдбреА),
CONSTRAINT callback_log_fk1 FOREIGN KEY (callback_id)
рд░реЗрдлрд░реА рд╕реВрддреНрд░реЛрдВ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ (рдЖрдИрдбреА) рдЕрджреНрдпрддрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╢рд░реНрдд рдкрд░ рдЬрд╛рд░реА рдХрд░реЗрдВ
)
рдЗрдВрдЬрди = INNODB

рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рд╕рдВрдкрд╛рджрди .conf

 exten => 88142590067, s, 1
     рд╡рд╣реА => n, рдЧреЛрдЯреЛрдЖрдИрдПрдл ($ ["$ {CALLERID (рд╕рдВрдЦреНрдпрд╛): 0: 4}" = "8814"]; рдЕрддрд┐рд░рд┐рдХреНрдд);  рдпрджрд┐ рд╕рдВрдЦреНрдпрд╛ рд╕реНрдерд╛рдиреАрдп рд╣реИ, рддреЛ рдХреЙрд▓рдмреИрдХ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ
 .... рдЖрдк рдпрд╣рд╛рдВ рдФрд░ рдЪреЗрдХ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ ...
     рд╡рд╣реА => n, рдЧреЛрдЯреЛ (рдХреЙрд▓)
     рд╡рд╣реА => n (рдЕрддрд┐рд░рд┐рдХреНрдд), NoOp ($ {CALLERID (рд╕рдВрдЦреНрдпрд╛)} рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ))
     рд╡рд╣реА => n, рд╕реЗрдЯ (ALLOW_CALLBACK = 1)
     рд╕рдорд╛рди => n, рд╕реЗрдЯ (CALLBACK_QUEUE = рдСрдкрд░реЗрдЯрд░)
     рд╕рдорд╛рди => n, рдкреГрд╖реНрдарднреВрдорд┐ (vse / press0-to-callback)

     рд╕рдорд╛рди => n (рдХреЙрд▓), NoOp (рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкреВрдЫреЗрдВред GROUP_COUNT = $ {GROUP_COUNT (рдСрдкрд░реЗрдЯрд░реНрд╕)})
     рд╡рд╣реА => n, рдХрддрд╛рд░ (рдСрдкрд░реЗрдЯрд░реЛрдВ, tThH)
     рд╡рд╣реА => рдПрди, рд╣реИрдВрдЧрдЕрдк

 рд╢рд╛рдорд┐рд▓ рд╣реИрдВ => main_menu_press

 [Main_menu_press]
 exten => 0.1, NoOp ('-------------------- $ {CALLERID (рд╕рдВрдЦреНрдпрд╛)} PRESS BUTTON $ {EXTEN}ред ALLOW_CALLBACK = $ {ALLOW_CALLBACK}ред ')
     рд╡рд╣реА => n, GotoIf ($ [$ {ALLOW_CALLBACK} = 1]; рдХреЙрд▓рдмреИрдХ, s, 1: i, 1)

 [рдХреЙрд▓рдмреИрдХ]
 ext => s, 1, NoOp (рдХреЙрд▓рдмреИрдХ)
     рд╡рд╣реА => n, рдкреНрд▓реЗрдмреИрдХ (рдзрдиреНрдпрд╡рд╛рдж-рдЖрдкрдХреЛ-рдХреЙрд▓рд┐рдВрдЧ рдФрд░ vse / my-vam-perezvonim)
     рд╡рд╣реА => рдПрди, рд╣реИрдВрдЧрдЕрдк

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

 [рдХреНрдпрд╛-рдХреЙрд▓рдмреИрдХ]
 exten => _Xред, 1, NoOp (рдкрдВрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдбрд╛рдпрд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ ($ {CALLBACK_QUEUE}) рдФрд░ $ {CALLBACK_NUM} рдкрд░ рдХреЙрд▓рдмреИрдХ рдХрд░реЗрдВ)
     рд╡рд╣реА => n, рд╕реЗрдЯ (__ DST = "?")
     рд╕рдорд╛рди => n, рд╕реЗрдЯ (CALLERID (рд╕рдВрдЦреНрдпрд╛) = $ {CALLBACK_NUM})
     рд╡рд╣реА => n (рдХреЙрд▓), рдХрддрд╛рд░ ($ {CALLBACK_QUEUE}, tT)
     рд╡рд╣реА => n, NoOp (рдХреЙрд▓рдмреИрдХ рдкреНрд░рд╢реНрдиреЛрддреНрддрд░ = $ {QUEUESTATUS})

 [рдореИрдХреНрд░реЛ-рдкрдВрдХреНрддрд┐-рдЬрд╡];  рдСрдкрд░реЗрдЯрд░ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдкрд░ рд╣рдо рдпрд╣рд╛рдВ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВред 
 exten => s, 1, NoOp (рдХрддрд╛рд░ рд╕рджрд╕реНрдп рдиреЗ рдЙрддреНрддрд░ рджрд┐рдпрд╛ uniq = $ {UNIQUEID} cid = $ {CALLERID (num)} рдЪрд╛рди = $ {CHANNEL} callback_id = $ [CALLBACK_ID} callback_num = $ {CALLBACK_NU
     рд╡рд╣реА => n, рдЧреЛрдЯреЛрдЖрдИрдПрдл ($ ["$ {CALLBACK_ID} x" = "x"])
     рд╕рдорд╛рди => n, рд╕реЗрдЯ (DST = $ {CHANNEL})
     рд╡рд╣реА => n, рд╕реЗрдЯ (CALLERID (рд╕рдВрдЦреНрдпрд╛) = 067)
     рд╡рд╣реА => рдПрди, рдкреНрд▓реЗрдмреИрдХ (рдирд┐рдЬреА-рдХреЛрд╢рд┐рд╢);  рдкреНрд▓реЗ рдСрдкрд░реЗрдЯрд░ "рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ"
     рд╡рд╣реА => n, рдПрдЧреА (рдХреЙрд▓рдмреИрдХред рдПрдлрдкреА, рдХрддрд╛рд░-рдЙрддреНрддрд░ рджреЗрдиреЗ рд╡рд╛рд▓рд╛, $ {CALLBACK_ID}, $ {CHANNEL}, $ {UNIQUEID})
     рд╡рд╣реА => n, рдбрд╛рдпрд▓ (рд╕реНрдерд╛рдиреАрдп / $ {CALLBACK_NUM} @from_office_new)
     рд╡рд╣реА => n, NoOp ([рдореИрдХреНрд░реЛ-рдХрддрд╛рд░-рдЙрддреНрддрд░] рдбрд╛рдпрд▓ рдЯрд╛рдЗрдордЖрдЙрдЯ)
     рд╡рд╣реА => n (рдЫреЛрдбрд╝реЗрдВ), NoOp ()

 exten => h, 1, NoOp ([рдореИрдХреНрд░реЛ-рдХрддрд╛рд░-рдЙрддреНрддрд░ рджреЗрдиреЗ рд╡рд╛рд▓рд╛] рдбрд╛рдпрд▓ рд╣реИрдВрдЧрдЕрдк)
     рд╡рд╣реА => n, рдЧреЛрдЯреЛрдЖрдИрдПрдл ($ ["$ {CALLBACK_ID} x" = "x"])
     рд╡рд╣реА => n, NoOp (рдбрд╛рдпрд▓рд╛рд╕реНрдЯрд╕ = $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
     рд╡рд╣реА => n, NoOp (my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})
     рд╡рд╣реА => n, agi (callback.php, hangup-queue-answering, $ {CALLBACK_ID}, $ {CHANNEL}, $ {UNIQUEID})
     рд╡рд╣реА => n (рдЕрдВрдд), NoOp

 [рдХреЙрд▓рдмреИрдХ: рдкреВрд░реНрдг]
 exten => s, 1, NoOp (рдХреЙрд▓рдмреИрдХ рдкреВрд░реНрдгред CALLBACK_ID = $ {CALLBACK_ID}, uniq = $ {UNIQUEID}, dst = $ {DST} рдЪрд╛рди = = {CHANNEL}}
     рд╡рд╣реА => n, NoOp (рдбрд╛рдпрд▓рд╛рд╕реНрдЯрд╕ = $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
     рд╡рд╣реА => n, NoOp (my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})


Queues.conf рдлрд╝рд╛рдЗрд▓
 [рдСрдкрд░реЗрдЯрд░реНрд╕]
     рд░рд┐рдВрдЧрд┐рдиреНрдпреВрдЬ = рдирд╣реАрдВ
     strategy = rrmemory
     рд╕рдВрдЧреАрдд = рдбрд┐рдлрд╝реЙрд▓реНрдЯ
     рд╕рджрд╕реНрдп => рдПрд╕рдЖрдИрдкреА / 321
     рд╕рджрд╕реНрдп => рдПрд╕рдЖрдИрдкреА / 322
     рд╕рджрд╕реНрдп => рдПрд╕рдЖрдИрдкреА / 323
     рд╕рджрд╕реНрдп => рдПрд╕рдЖрдИрдкреА / 324
     рд╕рджрд╕реНрдп => рдПрд╕рдЖрдИрдкреА / 325
     рд╕рджрд╕реНрдп => рдПрдЬреЗрдВрдЯ / 1
     рд╕рджрд╕реНрдп => рдПрдЬреЗрдВрдЯ / 2
     рд╕рджрд╕реНрдп => рдПрдЬреЗрдВрдЯ / 3
     рд╕рджрд╕реНрдп => рдПрдЬреЗрдВрдЯ / 4
     рд╕рджрд╕реНрдп => рдПрдЬреЗрдВрдЯ / 5
     рд╕рдВрджрд░реНрдн = main_menu_press
     рд╕рдордпрдмрд╛рд╣реНрдп = реж
     рдШреЛрд╖рдгрд╛-рд╕реНрдерд┐рддрд┐ = рд╣рд╛рдБ
     рдШреЛрд╖рдгрд╛-рдЖрд╡реГрддреНрддрд┐ = ремреж
     рдЖрд╡рдзрд┐рдХ-рдШреЛрд╖рдгрд╛-рдЖрд╡реГрддреНрддрд┐ = 30
     queue-youarenext = рдХрддрд╛рд░- youarenext
     рд╕рджрд╕реНрдпрдордХрд╛рд░реЛ = рдХрддрд╛рд░-рдЙрддреНрддрд░


рдЦреИрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ (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; // **************************************** ?> 


рдФрд░ рд╣рдо рд╣рд░ 5 рдорд┐рдирдЯ рдореЗрдВ рд╕реБрдмрд╣ 8 рдмрдЬреЗ рд╕реЗ 8 рдмрдЬреЗ рдХреЗ рдмреАрдЪ рдХреЙрд▓ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдкреБрдирд░реНрдЬрдирди рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдХреЙрд▓рдмреИрдХ- regen.php рдлрд╝рд╛рдЗрд▓ рдбрд╛рд▓рддреЗ рд╣реИрдВред
рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдпрд╛рд╕ рдХреЗ рд╕рд╛рде, рджреЛрд╣рд░рд╛рдпрд╛ рдХреЙрд▓ рдХрд╛ рд╕рдордп 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/hi471500/


All Articles