Направление входящего вызова на последнего абонента, не дозвонившегося на номер
В этой статье будет описан сценарий обработки входящих вызовов, при котором вызов в первую очередь направляется на абонента, который последним набирал номер звонящего и не дозвонился. Может быть весьма полезным использование такого сценария в компаниях, сотрудники которых часто звонят на мобильные номера клиентов — чтобы клиент, перезвонив на городской номер, сразу дозвонился до сотрудника, который пытался с ним связаться.
(приведённые в статье инструкции рассчитаны на FreePBX 13 и любой совместимый с ним Asterisk)
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)
Таким образом, мы уже пристроили контекст 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».
На этом всё, удачных экспериментов.
Остались вопросы?
Я - Виталий Шелест, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.
категории
- DECT
- Linux
- Вспомогательный софт при работе с Asterisk
- Интеграция с CRM и другими системами
- Интеграция с другими АТС
- Использование Elastix
- Использование FreePBX
- Книга
- Мониторинг и траблшутинг
- Настройка Asterisk
- Настройка IP-телефонов
- Настройка VoIP-оборудования
- Новости и Статьи
- Подключение операторов связи
- Разработка под Asterisk
- Установка Asterisk
VoIP оборудование
ближайшие курсы
Новые статьи
10 доводов в пользу Asterisk
Распространяется бесплатно.
Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.
Безопасен в использовании.
Любое программное обеспечение может стать объектом интереса злоумышленников, в том числе телефонная станция. Однако, сам Asterisk, а также операционная система, на которой он работает, дают множество инструментов защиты от любых атак. При грамотной настройке безопасности у злоумышленников нет никаких шансов попасть на станцию.
Надежен в эксплуатации.
Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.
Гибкий в настройке.
Зачастую возможности Asterisk ограничивает только фантазия пользователя. Ни один конструктор шаблонов не сравнится с Asterisk по гибкости настройки. Это позволяет решать с помощью Asterisk любые бизнес задачи, даже те, в которых выбор в его пользу не кажется изначально очевидным.
Имеет огромный функционал.
Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.
Интегрируется с любыми системами.
То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.
Позволяет телефонизировать офис за считанные часы.
В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.
Отличная масштабируемость.
Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.
Повышает управляемость бизнеса.
Asterisk дает не просто набор полезных функций, он повышает управляемость организации, качества и комфортности управления, а также увеличивает прозрачность бизнеса для руководства. Достичь этого можно, например, за счет автоматизации отчетов, подключения бота в Telegram, санкционированного доступа к станции из любой точки мира.
Снижает расходы на связь.
Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.
Добрый день, вот не могу понять от куда АТС берет LC_TARGET_DEVICE ?
Соответственно звонок не возвращается. т.к. LC_TARGET_DEVICE пустой
У меня FreePBX 14.
Немного изменил:
[LAST_OUTBOUND_CALL_TO_NUMBER] dsn=asterisk_cdr readsql=SELECT
src
,disposition
,billsec
,channel
FROMcdr
WHEREdst
LIKE ‘%${SQL_ESC(${ARG1})}’ ANDcalldate
>=’${SQL_ESC(${ARG2})}’ ORDER BYcalldate
DESC LIMIT 1И в диалплане так:
same => n,Set(ARRAY(LC_LAST_CALL_SRC,LC_LAST_CALL_RESULT,LC_LAST_CALL_BILLSEC,LC_LAST_CALL_CHANNEL)=${ODBC_LAST_OUTBOUND_CALL_TO_NUMBER(${CALLERID(num)},${LC_MYSQL_DATE_FROM})})
same => n,Set(LC_TARGET_DEVICE=${CUT(LC_LAST_CALL_CHANNEL,\-,1)})