artem
14.12.2017
2742

Направление входящего вызова на последнего абонента, не дозвонившегося на номер звонящего

ODBC-функция для определения последнего абонента, который не дозвонился до номера звонящего

Определять последнего абонента, который звонил на номер звонящего, будем по данным из таблицы CDR с помощью ODBC-функции. ODBC-подключение к MySQL и запись CDR в таблицу MySQL по умолчанию настроены в FreePBX 13, для этого дополнительных действий не требуется.
ODBC-функции описываются в файле /etc/asterisk/func_odbc.conf (если этот файл не существует, просто создайте его), добавьте в файл следующую функцию:

[LAST_OUTBOUND_CALL_TO_NUMBER]
dsn=asteriskcdrdb
readsql=SELECT `src`,`disposition`,`billsec` FROM `cdr` WHERE `dst` LIKE ‘%${SQL_ESC(${ARG1})}’ AND `calldate`>=’${SQL_ESC(${ARG2})}’ ORDER BY `calldate` DESC LIMIT 1

DSN asteriskcdrdb в FreePBX 13 должен быть по умолчанию описан в файле /etc/asterisk/res_odbc_additional.conf, убедитесь, что это так. Для применения изменений в файле /etc/asterisk/func_odbc.conf, выполните в CLI Asterisk команду:

module reload func_odbc.so

или

module load func_odbc.so
(если модуль func_odbc.so ранее не был загружен)

 

Если всё сделано правильно, команда «core show function ODBC_LAST_OUTBOUND_CALL_TO_NUMBER» в CLI Asterisk должна выдать SQL-запрос, указанный в файле func_odbc.conf.

 

Приведение номера звонящего к общему виду

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

Для приведения номера звонящего к общему виду будет использоваться следующий контекст:

[sub-fix-cid]
exten => s,1,GotoIf($[${REGEX(«^[0-9]{7}$» ${CALLERID(num)})} = 0]?cont1)
same  => n,Set(CALLERID(num)=7495${CALLERID(num)})
same  => n,Set(CALLERID(ANI-num)=${CALLERID(num)})
same  => n,Goto(end)
same  => n(cont1),GotoIf(${REGEX(«^[78]?[2-9][0-9]{9}$» ${CALLERID(num)})}?fix_cid)same  => n,GotoIf(${REGEX(«^\+?7[2-9][0-9]{9}$» ${CALLERID(num)})}?fix_cid)
same  => n,Goto(end)
same  => n(fix_cid),Set(CALLERID(num)=7${CALLERID(num):-10})
same  => n,Set(CALLERID(ANI-num)=${CALLERID(num)})
same  => n(end),Return

Как видите, контекст приводит к общему виду только номера России, номера, непохожие на российские, будут оставлены без изменений. Также к коротким городским номерам подставляется 7495, поменяйте код города, если это требуестя (впрочем очень немногие провайдеры передают номер звонящего в таком виде).
Ещё обратите внимание на то, что номер звонящего приводится к виду 7XXXXXXXXXX (если требуется, поменяйте формат на более подходящий для своих задач).

Добавление своего диалплана для обработки входящих вызовов в FreePBX

Для приёма входящих вызовов от провайдера у FreePBX есть контекст from-trunk, но у пользователя есть полный контроль над тем, в какой контекст попадёт входящий вызов — просто укажите другой контекст в параметре транка context, и входящие вызовы пойдут туда. Следовательно, самый простой способ добавить в FreePBX свой диалплан для обработки входящих вызовов — принимать вызовы из транка провайдера в самописный контекст, затем переводить их в контекст from-trunk. Пример:

[from-trunk-pre]
exten => _X.,1,Set(DID_NUM=${EXTEN})
same  => n,Goto(process,1)
exten => _+X.,1,Set(DID_NUM=${EXTEN})
same  => n,Goto(process,1)
 
exten => process,1,Gosub(sub-fix-cid,s,1)
same  => n,Goto(from-trunk,${DID_NUM},1)

Edit trunk

Таким образом, мы уже пристроили контекст sub-fix-cid, диалплан, реализующий основной функционал, также будет вызываться из from-trunk-pre.

 

Диалплан для направления входящего вызова на последнего абонента, недозвонившегося на номер звонящего

Ниже приведён код контекста, реализующего описываемый сценарий.

[sub-dial-last-caller]
exten => s,1,GotoIf($[${LEN(${CALLERID(num)})} < 10]?end)
same  => n,Set(LC_MYSQL_DATE_FROM=${STRFTIME(${EPOCH},,%Y-%m-%d)} 00:00:00)
same  => n,Set(ARRAY(LC_LAST_CALL_SRC,LC_LAST_CALL_RESULT,LC_LAST_CALL_BILLSEC)=${ODBC_LAST_OUTBOUND_CALL_TO_NUMBER(${CALLERID(num):-10},${LC_MYSQL_DATE_FROM})})
same  => n,GotoIf($[«${LC_LAST_CALL_SRC}» = «»]?end)
same  => n,Set(LC_TARGET_DEVICE=${DB(DEVICE/${LC_LAST_CALL_SRC}/device)})
same  => n,GotoIf($[«${LC_TARGET_DEVICE}» = «»]?end)
same  => n,GotoIf($[«${EXTENSION_STATE(${LC_LAST_CALL_SRC}@ext-local)}» != «NOT_INUSE»]?end)
same  => n,GotoIf($[«${LC_LAST_CALL_RESULT}» = «ANSWERED» & ${LC_LAST_CALL_BILLSEC} > 4]?end)
same  => n,Macro(user-callerid)
same  => n,Gosub(sub-record-check,s,1(in,${LC_LAST_CALL_SRC},yes))
same  => n,Set(DIALSTATUS=)
same  => n,Dial(${LC_TARGET_DEVICE},15,t)
same  => n,ExecIf($[«${DIALSTATUS}» = «ANSWER»]?Hangup)
same  => n(end),Return

Поиск исходящих вызовов на номер звонящего производится с начала текущего дня. Обратите внимание на то, что вызов последнего звонящего осуществляется в том случае, когда последний исходящий вызов на номер звонящего не был отвечен или разговор длился меньше 5 секунд. Эти условия нетрудно изменить, если требуется — например, можно убрать условие полностью, тогда вызов будет маршрутизироваться на последнего звонящего вне зависимости от результата того звонка.
Также телефон последнего звонящего должен быть доступен и не занят.

 

Контекст sub-dial-last-caller можно вызывать с помощью Gosub из контекста from-trunk-pre после sub-fix-cid.

[from-trunk-pre]
exten => _X.,1,Set(PRE_DID_NUM=${EXTEN})
same  => n,Goto(process,1)
exten => _+X.,1,Set(PRE_DID_NUM=${EXTEN})
same  => n,Goto(process,1)
 
exten => process,1,Gosub(sub-fix-cid,s,1)
same  => n,Gosub(sub-dial-last-caller,s,1)
same  => n,Goto(from-trunk,${PRE_DID_NUM},1)

Учтите, что здесь приведён самый простой способ внедрения описываемого сценария в диалплан FreePBX, если требуется сперва проиграть звонящему какое-либо сообщение и/или переводить на последнего звонящего только в рабочее время, можно переходить на sub-dial-last-caller,s,1 из FreePBX с помощью модуля «Custom Destinations».

 

На этом всё, удачных экспериментов.

 
avatar
  Подписаться  
Уведомление о

Остались вопросы?

Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

Why Choose HUGE?

Unlimited pre-designed elements

Each and every design element is designed for retina ready display on all kind of devices

User friendly interface and design

Each and every design element is designed for retina ready display on all kind of devices

100% editable layered PSD files

Each and every design element is designed for retina ready display on all kind of devices

Created using shape layers

Each and every design element is designed for retina ready display on all kind of devices