Отправка уведомлений о пропущенных звонках из Asterisk

от автора

В данном посте я расскажу вам о возможностях отправки уведомлений о пропущенных звонках с помощью Asterisk. Я постараюсь привести простые примеры конфигурации и подробнее раскрыть данную тему, далее вы можете экспериментировать по своему усмотрению или потребностям. Asterisk предлагает довольно широкие возможности для решения различных задач, поэтому одну и ту же задачу можно решать по разному, главное результат — стабильная работа ваших сервисов.

Отправка отчета о пропущенном звонке на email

Что имеем:
Входящая многоканальная линия с номером +7 (495) 1234567, IVR, 4 оператора в очереди вызова.

Задачи:
1. Отправлять отчет о пропущенном звонке, с указанием номера звонящего, времени поступления звонка и времени ожидания на линии.
2. Если абонент ждал на линии более 10 секунд и по какой-либо причине положил трубку, не дождавшись ответа оператора — отправляем отчет о пропущенном звонке.
3. Заносить в БД (в текущем примере MySQL) данные о том, какой оператор в очереди ответил звонок и фиксируем время в которое разговор был завершен.

В качестве решения приведу пример конфигурации (один из возможных вариантов решения), с комментариями на самых интересных по-моему мнению моментах.
Вот так выглядит конфигурация IVR рабочего времени + очереди вызова:

[globals] CIDFILE=/etc/asterisk/inc-calls/call-noanswer SQLHOST=db.domain.ru SQLUSER=asterisksql SQLPASS=Gt6Rju8FkS SQLDB=asteriskdb IVRWORK=custom/IVR_company_wav  [incoming-74951234567] exten => h,1,Set(WAITTIME=10) exten => h,n,Set(CTALL=$[${CDR(duration)}]) exten => h,n,Set(CTANSWER=$[${CDR(billsec)}]) exten => h,n,Set(CTDTIME=$[${CTALL}-${CTANSWER}]) exten => h,n,NoOP(${CDR(disposition)}) exten => h,n,NoOP(${CTDTIME}) exten => h,n,GotoIf($["${CDR(disposition)}" = "NO ANSWER"]?timecheck:n1) exten => h,n(n1),GotoIf($["${CDR(disposition)}" = "BUSY"]?timecheck:n2) exten => h,n(n2),GotoIf($["${CDR(disposition)}" = "FAILED"]?timecheck:n3) exten => h,n(n3),GotoIf($["${CDR(disposition)}" = "ANSWERED"]?n4:misscall) exten => h,n(n4),MYSQL(Connect connid ${SQLHOST} ${SQLUSER} ${SQLPASS} ${SQLDB}) exten => h,n,MYSQL(Query resultid ${connid} UPDATE office_calls SET active=0 WHERE asterisk_id='${QID}') exten => h,n,MYSQL(Clear ${resultid}) exten => h,n,MYSQL(Disconnect ${connid}) exten => h,n(hang),Hangup() exten => h,n(timecheck),GotoIf($[${CTDTIME} > ${WAITTIME}]?misscall:hang) exten => h,n(misscall),Goto(noanswer,s,1) exten => s,1,NoOp(${CALLERID(num)}) exten => s,n,Set(CALLID=74951234567) exten => s,n,Set(CALLER=${CALLERID(num)}) exten => s,n,Set(__QID=${CDR(uniqueid)}) exten => s,n(begin),GotoIfTime(10:00-22:00,mon-sat,*,*?workdays:outofoffice) exten => s,n(workdays),NoOp(Incoming CALL from ${CALLERID(num)} to ${EXTEN}) exten => s,n,Answer() exten => s,n,ResetCDR(w) exten => s,n,Wait(1) exten => s,n,Background(${IVRWORK}) exten => s,n,Queue(operators,t,,,300,,startflag1) exten => s,n,NoOp(${DIALSTATUS}) exten => s,n,Goto(noanswer,s,1) exten => s,n,Hangup() 

Обратите внимание, что если работает IVR и требуется узнать точное время ожидания абонента на линии (в обратном случае, у вас посчитается и время, которое абонет слушал голосовое меню), то нужно после Answer() добавить ResetCDR(w). Еще один интересный момент — запись в БД нам нужно заносить как только оператор в очереди ответит на звонок — тут нам поможет макрос startflag1, который будет выполнен, как только любой оператор в очереди ответит на звонок.
Тут все довольно просто, если на вызов не ответили, переходим в контекст noanswer, который выглядит следующим образом:

[noanswer] exten => s,1,NoOp(UID CALL: ${UNIQUEID} / DATE: ${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)})) exten => s,n,Set(RANDOM=${RAND(1000,9999)}) exten => s,n,Set(COUNT=${DB(fwcid2/count)}) exten => s,n,GotoIf($[${ISNULL(${COUNT})}]?:nextstep) exten => s,n,Set(DB(fwcid2/count)=1) exten => s,n,NoOp() exten => s,n,NoOp(UNIQID = ${COUNT}) exten => s,n,Set(COUNT=$[${COUNT} + 1]) exten => s,n,Set(DB(fwcid2/count)=${COUNT}) exten => s,n,System(echo "Неотвеченный вызов с номера +7${CALLERID(NUM)} в ${STRFTIME(${EPOCH},,%H:%M)}" > ${CIDFILE}-${CALLERID(NUM)}-${COUNT}) exten => s,n,System(echo "" >> ${CIDFILE}-${CALLERID(NUM)}-${COUNT}) exten => s,n,System(echo "Время ожидания абонента на линии составило ${CTDTIME} сек" >> ${CIDFILE}-${CALLERID(NUM)}-${COUNT}) exten => s,n,System(echo "hello" | mutt -x -s "+74951234567: пропущенный звонок ${STRFTIME(${EPOCH},,%d.%m.%Y)} ${STRFTIME(${EPOCH},,%H:%M)}" -e "set from="voip@domain.ru"" -e 'set realname='Asterisk'' voip@domain.ru < ${CIDFILE}-${CALLERID(NUM)}-${COUNT}) exten => s,n,System(/bin/rm -f ${CIDFILE}-${CALLERID(NUM)}-${COUNT}) exten => s,n,Hangup() 

${STRFTIME(${EPOCH},,%H:%M)} — время поступления звонка.
${CALLERID(NUM)} — номер звонящего.
${COUNT} — по большей части пример работы с ASTBD, значение переменной добавляется в конец создаваемого файла, чтобы сделать его уникальным, на случай если с одного и того же номера, в одно и то же время поступит звонок.

Теперь о добавлении записей в таблицу MySQL.
${SQLHOST/SQLUSER/SQLPASS/SQLD} — данные переменные я определил в секции globals.
${QID} — переменная которую мы передаем в макрос, предварительно определив ее при входящем звонке ‘Set(__QID=${CDR(uniqueid)})’. Обратите внимание на два ведущих символа подчеркивания, позволяющих унаследовать переменную в макрос macro-startflag1.

[macro-startflag1] exten => s,1,Set(CALLID=74951234567) exten => s,n,MYSQL(Connect connid ${SQLHOST} ${SQLUSER} ${SQLPASS} ${SQLDB}) exten => s,n,MYSQL(Query resultid ${connid} INSERT INTO office_calls VALUES (NULL,'${STRFTIME(,GMT,%G-%m-%d %H:%M:%S)}',1,'${CALLID}','${CDR(src)}','${CDR(dstcha nnel):0:9}','${STRFTIME(,GMT,%G-%m-%d %H:%M:%S)}','${STRFTIME(,GMT,%G-%m-%d %H:%M:%S)}','${QID}')) exten => s,n,MYSQL(Clear ${resultid}) exten => s,n,MYSQL(Disconnect ${connid}) exten => s,n,Hangup() 

Рассмотрим еще одну задачу: требуется формировать XML файл при пропущенных звонках.
Формат файла должен быть следующего вида:

<?xml version="1.0" encoding="UTF-8"?> <callback_request>   <id>100XXXX</id> --- XXX какой-то уникальный идентификатор   <name></name> --- номер телефона, на который пришел звонок   <phone>123456</phone> --- номер телефона, с которого пришел звонок   <comment>Пропущенный звонок</comment>   <completed>false</completed>   <created_at>11.12.2012 - 17:19</created_at> --- дата звонка   <updated_at>11.12.2012 - 17:19</updated_at> --- дата звонка   <no_answer/> </callback_request> 

В решении задачи я воспользуюсь командой System() и perl- скриптом.
Установим XML::Writer

yum install perl-XML-Writer 

Скрипт /etc/asterisk/scripts/genxml.pl выглядит следующим образом:

#!/usr/bin/env perl  # Create XML file  use strict; use warnings; use XML::Writer;  # Out to file  #open STDOUT, ">", "REQUEST.20121211171903.xml" or die "$0: open: $!";  my $doc = new XML::Writer();  # Pring attributes  $doc->xmlDecl('UTF-8'); $doc->startTag("callback_request"); $doc->dataElement( id => "$ARGV[0]"); $doc->startTag( "name"); $doc->characters( "$ARGV[1]"); $doc->endTag( "name"); $doc->dataElement( phone => "$ARGV[2]"); $doc->dataElement( comment => "Пропущенный звонок"); $doc->dataElement( completed => "false"); $doc->dataElement( created_at => "$ARGV[3]"); $doc->dataElement( updated_at => "$ARGV[3]"); $doc->emptyTag( "no_answer"); $doc->endTag(); $doc->end(); 

Запуск скрипта производится следующим образом:

exten => s,n,System(/usr/bin/perl /etc/asterisk/scripts/genxml.pl "100${RANDOM}" "74951234567" "${CALLERID(NUM)}" "${STRFTIME(${EPOCH},,%d.%m.%Y - %H:%M)}" > /srv/www/domain.ru/xml/REQUEST.${STRFTIME(${EPOCH},,%Y%m%d%H%M%S)}.xml) 

Надеюсь данные материал будет полезен вам.
Спасибо за внимание.

ссылка на оригинал статьи http://habrahabr.ru/company/centosadmin/blog/162825/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *