Возврат звонка после безусловного / "слепого" перевода
Callback after unattended / blind transfer
В случае сопровождаемого перевода звонка (attended transfer) всё довольно просто: оператор переводит абонента А на абонента Б, общается какое-то время с абонентом Б (или ждет, пока тот ответит или не ответит) и когда оператор кладет трубку, абоненты А и Б начинают общаться между собой. В случае, если абонент Б занят или не отвечает, оператор снова соединяется с абонентом А и сообщает ему о невозможности соединиться с абонентом Б.
В случае "слепого" перевода звонка (unattended transfer или blind transfer) всё сложнее: оператор переводит абонента А на абонента Б, и сразу после такого перевода оператор отключается. При этом абонент А остается предоставлен судьбе: если абонент Б ему отвечает, то всё хорошо. Если же нет (например, абонент Б занят или не отвечает), то у абонента А в трубке раздаются короткие гудки, после чего ему остается только повесить трубку и попытаться еще раз дозвониться до оператора. Однако для фирм, которым важен каждый звонок, крайне нежелательны такие обрывы связи. Что же делать?
Есть несколько вариантов решения проблемы (подход только один: чтобы звонки не "терялись", т.е. в случае неответа/занятости абонента звонок переходил куда-либо, пока на него не ответят):
- Несколько команд Dial
- С использованием attended transfer вместо blind transfer
- С использованием TRANSFER_CONTEXT
Несколько команд Dial
Для всех номеров в диалплане после команды Dial выполняется проверка результатов звонка, и если переменная DIALSTATUS не равна ANSWER (т.е. абонент занят, номер недоступен, на звонок не ответили и т.п.), то выполненяется следующая команда Dial, соединяющая абонента например, с секретарем. В случае неответа секретаря (что тоже возможно) выполняется третья команда Dial, ну и так далее.
С использованием attended transfer вместо blind transfer
Можно переделать attended transfer (сопровождаемый звонок), чтобы в случае неответа абонента звонок возвращался к тому, кто сделал перевод. Для этого в файле features.conf есть опции:
Рассмотрим ситуацию: абонент А звонит абоненту Б и пообщавшись с ним, просит перевести его на абонента С. Если абонент Б (делая attended transfer) дожидается ответа абонента С, возможно общается с ним, и отключается - то абоненты А и С связываются между собой и общаются. Это стандартный сопровождаемый перевод.
Если же абонент Б делает attended transfer на абонента С и сразу (не дожидаясь ответа) кладет трубку, то получается примерно та же ситуация, что и в случае blind transfer. Однако, всё хорошо только в случае, если абонент С снял трубку (или абонент А не дождавшись ответа, положил трубку сам).
atxferdropcall = yes - после неответа абонента С (или если этот абонент занят / сбросил вызов) происходит разрыв соединения, и абоненту А надо снова совершать звонок.
atxferdrpcall = no - теоретически, после неответа (или занятости/сброса звонка) абонента С, звонок абонента А должен вернуться обратно. Однако:
- пока абонент С не ответит (или абонент А не положит трубку, или пока не истечет время ответа абонента С и связь прервется сама) абонент Б не может разговаривать по телефону, его телефон в состоянии hold (абонент Б не может совершать и принимать вызовы);
- вернуться назад звонок (к абоненту Б) тоже не может (поскольку абонент Б положил трубку и теоретически разговор прервался, но его телефон по-прежнему в состоянии hold, т.е. занят), это чётко видно в случае, если стоит лимит на одновременные звонки, call-limit=1
Эту проблему призвана пофиксить (насколько я понимаю, это временное решение!) переменная ATXFER_NULL_TECH в файле features.c, который находится в каталоге main с исходными кодами астериска. Достаточно сделать поиск по этому файлу, и раскомментировать (убрать символы "//") строку:
//#define ATXFER_NULL_TECH 1
после чего пересобрать (и перезапустить разумеется) астериск.
Только в случае включения этой переменной, пересборки астериска и выставления atxferdrpcall = no, другие переменные имеют смысл:
atxfercallbackretries - количество попыток вернуть звонок абоненту Б (если он уже снова занят)
atxferloopdelay - задержка между попытками вернуть звонок абоненту Б.
С использованием TRANSFER_CONTEXT
Это, вероятно, самый интересный вариант с возвратом звонков после "слепого" перевода. Зачастую необходимость перевести звонок на другого абонента возникает не только у секретаря. Представьте себе фирму (к примеру, тот же call-центр), в котором осуществляются консалтинговые услуги. При этом множестов "секретарей" переводят звонки на специалистов, специалисты могут переводить звонки друг на друга, и зачастую нет времени (и желания) переведя звонок, дожидаться ответа того, на кого этот звонок переводится - а хочется перенаправить звонок на нужного сотрудника, чтобы в случае, если человека нет на месте (или он занят) звонок вернулся обратно автоматически. Таким образом, звонок должен возвращаться не "кому-нибудь", а именно тому человеку, который его перевел.
В этом случае для всех переводимых звонков настраивается отдельный контекст, в котором они будут обрабатываться (задав значение переменной TRANSFER_CONTEXT). При этом контролируется, был ли ответ на этот переведенный звонок, и при необходимости (используя переменную BLINDTRANSFER) можно вернуть звонок тому абоненту, который осуществлял перевод вызова:
Обратите внимание: в данном примере возможны переводы звонков только на "реальных" людей (т.е. только на SIP-абонентов). В общем же случае Вы можете захотеть переводить звонки на группы номеров, либо на номера с обработкой (в extensions.conf) до или после вызова. В этом случае Вы можете обратиться за консультацией к автору сайта, на нашем предприятии это реализовано (и работает).
Внимание: в описанном выше способе возврата звонка с помощью transfer_context обнаружен небольшой баг, ну или особенность реализации: номер того, кто переводит звонок и номер, куда переводят звонок, должны совпадать по длине. Если (например) у Вас в организации 4-значные номера и Вы переводите звонок на мобильный, то в случае, когда человек не дозвонился, звонок не вернется обратно (будет неправильный номер в OrigNumber). А если (вдруг) у Вас в организации используется много номеров и они могут различаться по длине (например: в одной и той же организации номера 11...19 и 300..399), то описанный выше вариант (с transfer_context) Вам однозначно придется переделывать.
P.S. Обратите также внимание на то, что с точки зрения безопасности asterisk, в контексте перевода звонков использован неправильный шаблон. Подробнее об этом см. статьи по безопасности asterisk в разделе Asterisk.
Статья обновлена: 31.07.2016
|