Не большая предыстория
На работе периодически приходится перехватывать вызовы, что в принципе не беда. Но бывает, что необходимо потом перезвонить тому, кто звонил.
Номер соответственно у меня не высветился и обычно приходится лезть в cdr'ки в mysql или подойти к телефону напарника и искать номер телефона.
Можно в принципе попросить напарника включать переадресацию на телефонном аппарате, но уходит он на пару минут, да и мы не ищем легких путей.
Итак, что мы имеем: офисная АТС на Asterisk (версия = 1.8.15.1), реализована функция перехвата вызова и уведомлений о звонке через jabber.
Информации по поводу настройки перехвата вызова, отправки уведомлений c помощью jabber достаточно в просторах интернета, так что сразу опишу о реализации получения уведомления при перехвате вызова.
Начнем с Mysql (версия = Server version: 5.5.31-0+wheezy1 (Debian)):
В базе asteriskcdrdb создадим 2 таблицы pickup_message и pickup_group.
В таблице pickup_message, у нас будет всего 2 столбца pg_id и message:
pg_id — id pickup группы в Asterisk;
message — поле куда будут записываться уведомления;
mysql> CREATE TABLE pickup_message
-> (pg_id smallint unsigned,
Параметры SMALLINT и UNSIGNED для столбца pg_id, выбрал т.к. планируются только короткие, целые числа. Хотя можно использовать и имена для групп перехвата.
-> message varchar(128),
-> CONSTRAINT pk_pg_id PRIMARY KEY (pg_id)
В столбце pg_id у нас будут только уникальные записи, и столбец будет служить для связки 2-х таблиц.
-> );
Query OK, 0 rows affected (0.09 sec)
Таблица pickup_group содержит информацию о принадлежности внутреннего номера (peer) к определенной группе перехвата (pg_id).
Так же для связки 2 таблиц добавим FOREIGN KEY () и REFERENCES.
mysql> CREATE TABLE pickup_group
-> (pg_id SMALLINT UNSIGNED,
-> peer SMALLINT UNSIGNED,
-> CONSTRAINT fk_pg_id FOREIGN KEY (pg_id)
-> REFERENCES pickup_message (pg_id)
-> );
Query OK, 0 rows affected (0.08 sec)
Заполним для теста обе таблицы следующей информацией группа перехвата 1, внутренние номера 309 и 373:
mysql> insert into pickup_message values (1, NULL);
Query OK, 1 row affected (0.05 sec)
mysql> insert into pickup_group values (1, 309);
Query OK, 1 row affected (0.06 sec)
mysql> insert into pickup_group values (1, 373);
Query OK, 1 row affected (0.04 sec)
mysql> select * from pickup_message;
+-------+---------+
| pg_id | message |
+-------+---------+
| 1 | NULL |
| 33 | NULL |
+-------+---------+
2 rows in set (0.00 sec)
mysql> select * from pickup_group;
+-------+------+
| pg_id | peer |
+-------+------+
| 1 | 309 |
| 1 | 373 |
+-------+------+
2 rows in set (0.00 sec)
Переходим к настройкам Asterisk, отредактируем extensions.conf:
В контексте где обрабатывается набор внутренних номеров:
exten => _ZXX,1,Macro(jabb-personal-pickup,${EXTEN})
same => n,Dial(SIP/${EXTEN},120,t)
same => n,Hangup
Макрос для отправки уведомлений (в макрос передается одна переменная ${ARG1}, номер который набрали):
[macro-jabb-personal-pickup]
exten => s,1,Set(text=Входящий вызов от ${CALLERID(number)})
same => n,MYSQL(Connect connid 127.0.0.1 root PASSWORD asteriskcdrdb)
same => n,MYSQL(Query resultid ${connid} select pickup_message.pg_id from pickup_message inner join pickup_group where peer = '${ARG1}';) ; #в данном запросе ищем к какой группе относится номер который набрали
same => n,MYSQL(Fetch fetchid ${resultid} pg_id)
same => n,GotoIf($["${fetchid}"="1"]?yes:no)
same => n(yes),MYSQL(Query resultid ${connid} update pickup_message set message ='${text}' where pg_id = '${pg_id}') ; #если номер есть в группе, то запишем в ячейку группы message переменную text
same => n(no),MYSQL(Clear ${resultid})
same => n,MYSQL(Query resultid ${connid} select jabb_id from jabber where number=${ARG1})
same => n,MYSQL(Fetch fetchid ${resultid} jabb_id)
same => n,GotoIf($["${fetchid}"="1"]?ok:bad)
same => n(ok),JabberSend(asterisk,${jabb_id},${text})
same => n(bad),MYSQL(Clear ${resultid})
same => n,MYSQL(Disconnect ${connid})
И собственно контекст при перехвате звонка (*8). Здесь мы проверяем к какой группе мы относимся и есть ли сообщения в нашей группе.
Т.е. при входящем звонке на внутренний номер, в ячейку группы записывается информация о звонящем, а перехватом мы эту информацию забираем.
В принципе все просто:
exten => *8,1,NoOp(pickup)
same => n,MYSQL(Connect connid 127.0.0.1 root PASSWORD asteriskcdrdb)
same => n,MYSQL(Query resultid ${connid} select pickup_message.message from pickup_message inner join pickup_group where peer = ${CALLERID(number)}) ; #запрос на проверку к какой группе перехвата мы относимся
same => n,MYSQL(Fetch fetchid ${resultid} message)
same => n,GotoIf($["${fetchid}"="1"]?message:no) ; #проверяем что в запросе есть результат
same => n(message),Set(text=Перехват вызова. ${message}) ;# в переменную text запишем данные из ячейки нашей группы
same => n,MYSQL(Clear ${resultid})
same => n,MYSQL(Query resultid ${connid} select jabb_id from jabber where number=${CALLERID(number)}) ;# ищем id jabber для peer'a, т.к. не все его используют
same => n,MYSQL(Fetch fetchid ${resultid} jabb_id)
same => n,GotoIf($["${fetchid}"="1"]?yes:no) ; # проверяем что в запросе есть результат
same => n(yes),JabberSend(asterisk,${jabb_id},${text})
same => n(no),MYSQL(Clear ${resultid})
same => n,MYSQL(Query resultid ${connid} update pickup_message set message ='NULL' where message = '${message}')
same => n,MYSQL(Disconnect ${connid})
same => n,PickUP()
В итоге, при перехвате вызова, в jabber приходят сообщения такого рода:
[15:09:07] <Office Manager> Перехват вызова. Персональный звонок. 302
[15:12:08] <Office Manager> Перехват вызова. Персональный звонок. 226
[15:25:47] <Office Manager> Перехват вызова. Персональный звонок. 106
[15:32:40] <Office Manager> Персональный звонок. 116
Надеюсь, для кого-то данная информация будет полезной.
Автор: Hes