Мобильные динамические агенты в очереди (Удаленное подключение к очереди мобильных телефонов)

Данная статья взята из базы знания компании VoxLink, в код внесены изменения, для возможности ограничения подключаемых мобильных номеров.

 

В данной статье рассмотрим возможность добавления в очередь мобильных номеров в качестве динамических агентов.

Постановка задачи

Роль динамического агента позволяет присоединиться к очереди или выйти из неё в любое время, набрав сервисный код.

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

Задача: реализовать возможность входа мобильного номера в очередь и выхода из неё посредством набора сервисного кода в голосовом меню.

 

Реализация+

Для начала разберёмся, почему при звонке с мобильного номера на АТС и донаборе сервисного кода не может попасть в очередь в качестве динамического агента, даже если он там прописан. Проблема состоит в следующем: при входе/выходе устройства в качестве динамического агента в очередь происходит проверка его текущего состояния. Asterisk может сделать это для заведённых на нём пиров, однако для мобильного номера проверять ему нечего. Следовательно, нам нужно отключить проверку состояния для мобильного номера.

В файле extensions_custom.conf (/etc/asterisk/) пропишем:

[app-queue-toggle-mob]
exten => s,1(start),Answer
exten => s,n,NoOp("app-queue-toggle-mobile")
exten => s,n,Wait(1)
exten => s,n,Macro(user-callerid,)
exten => s,n,Set(QUEUEUSER=${CALLERID(num)})
exten => s,n,Set(result=${ODBC_CHECK_NUM(${QUEUEUSER})})
exten => s,n,GotoIf($[${result} = 0]?logout)
exten => s,n,Set(QUEUESTAT=LOGGEDOUT)
exten => s,n,Set(QUEUENO=8008)
exten => s,n,AGI(queue_devstate.agi,getqueues,${QUEUEUSER})
exten => s,n,GotoIf($["${QUEUESTAT}" = "LOGGEDOUT"]?activate)
exten => s,n,GotoIf($["${QUEUESTAT}" = "LOGGEDIN"]?deactivate:end)
exten => s,n(deactivate),Noop(Agent Logged out)
exten => s,n,Macro(toggle-del-agent-mob,)
exten => s,n(logout),Set(STATE=NOT_INUSE)
exten => s,n,Playback(agent-loggedoff)
exten => s,n,Macro(hangupcall,)
exten => s,n(activate),Noop(Agent Logged In)
exten => s,n,Macro(toggle-add-agent-mob,)
exten => s,n,GotoIf($["${QAGENT_UNAUTHORIZED}"="1"]?logout)
exten => s,n,Playback(agent-loginok)
exten => s,n,SayDigits(${QUEUEUSER})
exten => s,n,Macro(hangupcall,)

В контексте app-queue-toggle-mob происходит следующее: присваиваем в QUEUEUSER номер, который находится в CALLERID(num), а также в QUEUENO прописываем номер очереди, в которую должен попасть мобильный номер. QUEUESTAT при этом изначально содержит в себе LOGGEDOUT, так как первоначально данное состояние в очереди актуально для всех динамических агентов. Затем происходит сбор информации о том, есть ли агент QUEUEUSER в очереди в данный момент или нет. Если есть, то в какой очереди. За эту часть контекста отвечает скрипт queue_devstate.agi. Далее, на основе данной информации, в QUEUESTAT присваивается актуальный статус динамического агента и происходит вызов макросов для его удаления или добавления. Макрос для добавления в очередь изначально работает с хинтами, и его нужно переписать. Переписываем в этом же файле.

 

[macro-toggle-add-agent-mob]
exten => s,1,Macro(user-callerid,SKIPTTL,)
exten => s,n,Set(QUEUEUSER=${IF($[${LEN(${QUEUEUSER})}>0]?${QUEUEUSER}:${AMPUSER})})
exten => s,n,Set(QUEUEUSERCIDNAME=${DB(AMPUSER/${QUEUEUSER}/cidname)})
exten => s,n,GotoIf($["${DB(QPENALTY/${QUEUENO}/dynmemberonly)}" = "yes" & ${DB_EXISTS(QPENALTY/${QUEUENO}/agents/${QUEUEUSER})} != 1]?invalid)
exten => s,n,AddQueueMember(${QUEUENO},Local/${QUEUEUSER}@outbound-allroutes/n,${DB(QPENALTY/${QUEUENO}/agents/${QUEUEUSER})},,${QUEUEUSERCIDNAME})
exten => s,n,UserEvent(AgentLogin,Agent: ${QUEUEUSER})
exten => s,n,QueueLog(${QUEUENO},MANAGER,${IF($[${LEN(${QUEUEUSERCIDNAME})}>0]?${QUEUEUSERCIDNAME}:${QUEUEUSER})},ADDMEMBER,)
exten => s,n,MacroExit()
exten => s,n(invalid),Playback(pbx-invalid)
exten => s,n,Set(QAGENT_UNAUTHORIZED=1)
exten => s,n,MacroExit()

В AddQueueMember обязательно указываем Local/”мобильный номер”@”маршрут”, иначе вызов из очереди на агента не уйдёт.

Также перепропишем макрос для удаления агента.

[macro-toggle-del-agent-mob]
exten => s,1,Macro(user-callerid,SKIPTTL,)
exten => s,n,Set(QUEUEUSER=${IF($[${LEN(${QUEUEUSER})}>0]?${QUEUEUSER}:${AMPUSER})})
exten => s,n,Set(QUEUEUSERCIDNAME=${DB(AMPUSER/${QUEUEUSER}/cidname)})
exten => s,n,RemoveQueueMember(${QUEUENO},Local/${QUEUEUSER}@outbound-allroutes/n)
exten => s,n,UserEvent(RefreshQueue)
exten => s,n,QueueLog(${QUEUENO},MANAGER,${IF($[${LEN(${QUEUEUSERCIDNAME})}>0]?${QUEUEUSERCIDNAME}:${QUEUEUSER})},REMOVEMEMBER,)
exten => s,n,MacroExit()

В RemoveQueueMember указываем тот же маршрут, что и в AddQueueMember. Иначе удаление агента происходить не будет.

В контексте app-queue-toggle-mob  прописана проверка номера на присутствии в базе разрешенных мобильных номеров.

exten => s,n,Set(result=${ODBC_CHECK_NUM(${QUEUEUSER})}) 
exten => s,n,GotoIf($[${result} = 0]?logout)

Для работы необходимо создать базу в которой будет список разрешенных мобильных номеров.

Так же необходимо следующие настройки:

В файле func_odbc.conf

[CHECK_NUM]
dsn=mobile_nmbr
readsql=select count(*) from db where number like '%${ARG1}'

где db – имя таблице, number – поле с номером телефона. Используем like, так как некоторые операторы присылают CallerID без “8”.

В файле res_odbc_custom.conf прописываем

[mobile_nmbr]
enabled=>yes
dsn=>mobile_nmbr
pooling=>no
limit=>1
pre-connect=>yes
username=>user_my_sql
password=>password_user

и в файле etc/odbc.ini

[mobile_nmbr]
Driver=MySQL
Description=MySQL to Mobile Agent
Server=localhost
Port=3306
Database=mobile_nmbr
Option=3

После того, как переписали контекст, перейдём на web-интерфейс в модуль Custom Destination (Admin-> Custom Destinations).

Здесь создадим новое назначение, которое будет ссылаться на контекст appqueuetogglemob.

 

Далее перейдём в IVR и в донабор впишем новую строчку с переходом на созданное назначение.

В целях безопасности рекомендуем в донабор вписать неиспользуемый сервисный код или любую сложную комбинацию цифр. В противном случае возможно случайное попадание клиента в очередь.

В примере в донабор впишем кастомный сервисный код *4580.

Теперь проверим работу.

Обращаем внимание на следующее: вписывать мобильный номер в очередь в качестве динамического агента необязательно, т.к. ранее в контексте app-queue-toggle-mob мы указали номер очереди в переменной.

Позвоним с мобильного номера на внешний номер АТС. После того, как попали в IVR, донаберём сервисный код *4580.

В логе видим, что вызов пришёл с такого-то номера. После того, как был набран сервисный код, в консоли появился NOTICE о том, что агент зарегистрирован в очереди 8008. Также после этого в телефоне услышим сообщение о том, что агент с номером 79112223344 зарегистрирован добавлен в очередь.

Выйти из очереди можно также звонком на IVR и донабором *4580.

Статусы агента в очереди

Важно отметить, что для мобильных динамических агентов также можно отследить статусы в очереди, как и для обычных агентов очереди. После входа в очередь введём в Asterisk CLI команду:

queue show <номер очереди>

Агент отобразится в статусу Not in use.

Также можно ввести данную команду, когда в очередь пришёл вызов, и агент на него ответил. Статус будет In Call.

 

Источник.