В одной конторе, являющейся страховым брокером, меня попросили сделать им такую систему, что бы сотрудники могли дозваниваться до клиентов, но в тоже время не знали бы их телефонные номера.
Я решил сделать небольшое приложение на PHP с использованием AMI (Asterisk Management Interface), которое могло бы по имени клиента находить его телефонный номер в базе MySQL и передавать его в Asterisk для звонка. Оформил с помощью Bootstrap и капли JQuery.
База данных на две таблицы – операторы:
1 2 3 4 5 6 7 8 |
CREATE TABLE users ( user_id MEDIUMINT NOT NULL AUTO_INCREMENT, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, PRIMARY KEY (user_id), UNIQUE KEY username (username) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; |
И клиенты:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
create table clients ( id MEDIUMINT NOT NULL AUTO_INCREMENT, number MEDIUMINT NOT NULL, op MEDIUMINT NOT NULL, firstname VARCHAR(255) NOT NULL, lastname VARCHAR(255) NOT NULL, age MEDIUMINT NOT NULL, exp MEDIUMINT NOT NULL, phonenumber BIGINT NOT NULL, model VARCHAR(255) NOT NULL, year MEDIUMINT NOT NULL, cc MEDIUMINT NOT NULL, cost MEDIUMINT NOT NULL, PRIMARY KEY (id), UNIQUE KEY number(number) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; |
За каждым клиентом закрепляется оператор, который будет ему звонить. Вместо имени клиента было решено использовать номер полиса клиента. Вот метод дозвона из класса клиента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
function call($number){ $con=dbconnect(); $result = mysqli_query($con,"SELECT * FROM clients WHERE number = '$number'"); while($row = mysqli_fetch_assoc($result)){ $end = $row['end']; $comp = $row['comp']; $sk = $row['sk']; $firstname = $row['firstname']; $lastname = $row['lastname']; $age = $row['age']; $exp = $row['exp']; $model = $row['model']; $year = $row['year']; $cc = $row['cc']; $cost= $row['cost']; $phonenumber = $row['phonenumber']; $op = $row['op']; } $errno=""; $errstr=""; $asterisk_ip=settings::asterisk_ip; $asterisk_port=settings::asterisk_port; $asterisk_trunk=settings::asterisk_trunk; $asterisk_user=settings::asterisk_user; $asterisk_pass=settings::asterisk_pass; $socket = fsockopen($asterisk_ip, $asterisk_port, $errno, $errstr, 20); fputs($socket,"Action: Login\r\n"); fputs($socket,"UserName: $asterisk_user\r\n"); fputs($socket,"Secret: $asterisk_pass\r\n\r\n"); fputs($socket, "Action: Originate\r\n" ); fputs($socket, "Channel: SIP/$asterisk_trunk/$phonenumber\r\n" ); fputs($socket, "Exten: $op\r\n" ); fputs($socket, "Context: default\r\n" ); fputs($socket, "Priority: 1\r\n" ); fputs($socket, "Timeout: 20000\r\n" ); fputs($socket, "CallerID: $number\r\n"); fputs($socket, "Async: yes\r\n\r\n" ); fputs($socket,"Action: Logoff\r\n\r\n"); sleep(2); fclose($socket); echo "<div class="info">"; echo "Звоню клиенту: $firstname $lastname Возраст: $age Стаж: $exp Марка: $model Год: $year Объём: $cc Стоимость: $cost Страховая компания: $sk"; echo "</div>"; } |
Asterisk будет звонить на телефонный номер клиента и соединять его с внутренним номером оператора. В базу CDR будет заноситься звонок c CalledID равным номеру полиса клиента. Я использовал mysql_cdr но можно использовать и odbc_cdr.
Для того что бы обратные звонки клиентов приходили на оператора, который разговаривал с клиентом, был написан следующий dial plan:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[clip_routing] Берём трубку exten => 888,1,Answer() Отрезаем всё не нужное от входящего номера exten => 888,n,Set(NUM=${SHELL(echo ${CALLERID(number)} |tr -d '\n' |sed 's/^..//')}) Подключаемся к базе клиентов exten => 888,n,MYSQL(Connect connid localhost root паролик имябазы) Выбираем клиента с таким же телефонным номером exten => 888,n,MYSQL(Query resultid ${connid} SELECT `number` FROM clients WHERE `phonenumber` LIKE '%${NUM}%' ORDER BY `id` DESC LIMIT 1) Находим номер полиса этого клиента exten => 888,n,MYSQL(Fetch fetchid ${resultid} NUMBER) exten => 888,n,MYSQL(Clear ${resultid}) Подключаемся к базе записей Asterisk exten => 888,n,MYSQL(Connect connid localhost root Avalon2014 asteriskcdrdb) Находим внутренний номер оператора с которым разговаривал клиент exten => 888,n,MYSQL(Query resultid ${connid} SELECT `dst` FROM cdr WHERE `clid` LIKE '${NUMBER}' ORDER BY `calldate` DESC LIMIT 1) exten => 888,n,MYSQL(Fetch fetchid ${resultid} VAR) exten => 888,n,MYSQL(Clear ${resultid}) exten => 888,n,MYSQL(Disconnect ${connid}) exten => 888,n,Set(CHAN=${SHELL(echo ${var} |tr -d '\n')}) exten => 888,n,MYSQL(Disconnect ${connid}) Меняем телефонный номер клиента на номер его полиса exten => 888,n,Set(CALLERID(number)=${NUMBER}) Проверяем, есть ли внутренний номер, с которым разговаривал клиент exten => 888,n,Gotoif($[0${CHAN} > 0]?dial1) Если нет то звоним на входящий (queue или callgroup) exten => 888,n,Goto(from-internal,100,1) exten => 888,n,Hangup() А если клиент разговаривал с оператором ранее то звоним оператору exten => 888,n(dial1),Goto(from-internal,${CHAN},1) |
https://github.com/kirfog/telefonisk