Rückruf oder „Steigerung der Kundenbindung“

Es gibt ein Sternchen, eine Gruppe von Bedienern (3-5 Personen) mit einer großen Last (durchschnittliche Wartezeit> 2 Minuten)

Die Aufgabe besteht darin, dass Teilnehmer mit einer bestimmten geografischen Lage die Möglichkeit haben, nicht zu warten, bis der Betreiber frei ist, und durch Drücken von 0 „Danke für den Anruf“ zu hören. Wir werden Sie auf jeden Fall zurückrufen. “Trennen Sie die Verbindung und warten Sie ruhig auf einen Anruf vom Betreiber, oder von den normalen Leuten per Smart Callback

Erstellen Sie Tabellen
CREATE TABLE asterisk.callback (
id int (11) NICHT NULL AUTO_INCREMENT,
dt timestamp DEFAULT CURRENT_TIMESTAMP,
cid varchar (32) STANDARD NULL,
dst varchar (32) STANDARD NULL,
Status smallint (6) NOT NULL DEFAULT 0,
tot_calls int (11) NOT NULL DEFAULT 0,
last_call timestamp DEFAULT '0000-00-00 00:00:00',
compl_dt timestamp DEFAULT '0000-00-00 00:00:00',
uniqueid varchar (32) STANDARD NULL,
Warteschlange varchar (255) DEFAULT NULL,
Primärschlüssel (ID)
)
ENGINE = INNODB

CREATE TABLE asterisk.callback_log (
id int (11) NICHT NULL AUTO_INCREMENT,
callback_id int (11) NICHT NULL,
dt timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
Status varchar (32) STANDARD NULL,
params varchar (2048) STANDARD NULL,
Primärschlüssel (ID),
CONSTRAINT callback_log_fk1 AUSLÄNDISCHER SCHLÜSSEL (callback_id)
REFERENZEN asterisk.callback (id) ON DELETE CASCADE ON UPDATE CASCADE
)
ENGINE = INNODB

Bearbeiten von extensions.conf

 exten => 88142590067, s, 1
     same => n, GotoIf ($ ["$ {CALLERID (num): 0: 4}" = "8814"]? extra);  Wenn die Nummer lokal ist, lassen Sie CALLBACK zu
 .... hier können Sie weitere Schecks einfügen ...
     same => n, Goto (Anruf)
     same => n (extra), NoOp (Rückruf für $ {CALLERID (num)} zulassen)
     same => n, Set (ALLOW_CALLBACK = 1)
     same => n, Set (CALLBACK_QUEUE = Operatoren)
     same => n, Hintergrund (vse / press0-to-callback)

     same => n (Aufruf), NoOp (Nach Operatoren fragen. GROUP_COUNT = $ {GROUP_COUNT (Operatoren)})
     same => n, queue (Operatoren, tThH)
     same => n, Auflegen

 include => main_menu_press

 [main_menu_press]
 exten => 0.1, NoOp ('-------------------- $ {CALLERID (num)} DRUCKTASTE $ {EXTEN}. ALLOW_CALLBACK = $ {ALLOW_CALLBACK} ')
     same => n, GotoIf ($ [$ {ALLOW_CALLBACK} = 1]? Rückruf, s, 1: i, 1)

 [Rückruf]
 exten => s, 1, NoOp (CALLBACK)
     same => n, Wiedergabe (danke für den Anruf & vse / my-vam-perezvonim)
     same => n, Auflegen

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

 [Rückruf]
 exten => _X., 1, NoOp (Versuchen Sie, in die Warteschlange zu wählen ($ {CALLBACK_QUEUE}) und rufen Sie $ {CALLBACK_NUM} zurück)
     same => n, Set (__ DST = "?")
     same => n, Set (CALLERID (num) = $ {CALLBACK_NUM})
     same => n (Aufruf), Warteschlange ($ {CALLBACK_QUEUE}, tT)
     same => n, NoOp (CALLBACK QUEUESTATUS = $ {QUEUESTATUS})

 [Makro-Warteschlangen-Antwort];  Wir kommen hierher, als der Betreiber antwortete. 
 exten => s, 1, NoOp (Warteschlangenmitglied beantwortet uniq = $ {UNIQUEID} cid = $ {CALLERID (num)} chan = $ {CHANNEL} callback_id = $ {CALLBACK_ID} callback_num = $ {CALLBACK_NU
     same => n, GotoIf ($ ["$ {CALLBACK_ID} x" = "x"]? überspringen)
     same => n, Set (DST = $ {CHANNEL})
     same => n, Set (CALLERID (num) = 067)
     same => n, Wiedergabe (priv-try);  Spielbetreiber "Warte auf Verbindung"
     same => n, agi (callback.php, Warteschlangenantwort, $ {CALLBACK_ID}, $ {CHANNEL}, $ {UNIQUEID})
     same => n, Dial (Local / $ {CALLBACK_NUM} @from_office_new)
     same => n, NoOp (Zeitlimit für [Makrowarteschlange-Antwort] wählen)
     same => n (überspringen), NoOp ()

 exten => h, 1, NoOp ([Makro-Warteschlangen-Antwort] Dial Hangup)
     same => n, GotoIf ($ ["$ {CALLBACK_ID} x" = "x"]? end)
     same => n, NoOp (dialstatus = $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
     same => n, NoOp (my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})
     same => n, agi (callback.php, Auflegen der Warteschlange, $ {CALLBACK_ID}, $ {CHANNEL}, $ {UNIQUEID})
     gleich => n (Ende), NoOp

 [Rückruf abgeschlossen]
 exten => s, 1, NoOp (Rückruf abgeschlossen. CALLBACK_ID = $ {CALLBACK_ID}, uniq = $ {UNIQUEID}, dst = $ {DST} chan = $ {CHANNEL})
     same => n, NoOp (dialstatus = $ {DIALSTATUS} hangupcause = $ {HANGUPCAUSE} queuestatus = $ {QUEUESTATUS})
     same => n, NoOp (my_dialstatus = $ {MY_DIALSTATUS} my_hangupcause = $ {MY_HANGUPCAUSE})


Queues.conf-Datei
 [Betreiber]
     ringinuse = nein
     Strategie = Erinnerung
     Musik = Standard
     Mitglied => SIP / 321
     Mitglied => SIP / 322
     Mitglied => SIP / 323
     Mitglied => SIP / 324
     Mitglied => SIP / 325
     Mitglied => Agent / 1
     Mitglied => Agent / 2
     Mitglied => Agent / 3
     Mitglied => Agent / 4
     Mitglied => Agent / 5
     context = main_menu_press
     Zeitüberschreitung = 0
     Ankündigungsposition = ja
     Ansagefrequenz = 60
     periodische Ansagefrequenz = 30
     queue-youarenext = queue-youarenext
     membermacro = Warteschlange-Antwort


Nun, eigentlich die Skripte (PHP erkannt)

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; // **************************************** ?> 


Und wir legen alle 5 Minuten zwischen 8 und 20 Uhr eine weitere callback-regen.php-Datei für die Regeneration von Call-Dateien in Kronen ab.
Bei jedem Versuch wird die Zeit des wiederholten Anrufs um 5 Minuten erhöht. Stoppen Sie nach 10 Versuchen, den Bediener zu verspotten
 #!/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/de471500/


All Articles