Этот добавочный номер еще не закончен, но прервемся на мгновение и посмотрим, что уже сделано.

Когда агент по продажам занимает рабочий стол, он регистрируется, набирая собственный добавочный номер. В этом случае шаблоном 110[1-5] определены номера от 1101 до 1105. Так же просто можно задать менее жесткое ограничение, используя шаблон 11XX (разрешая номера в диапазоне от 1100 до 1199). Этот добавочный номер использует func_odbc для выполнения поиска с помощью функции диалплана HOTDESK_INFO() (созданием которой мы вскоре займемся). Эта специальная функция (описываемая в файле func_odbc.conf) реализует SQL-вы- ражение и возвращает все, что извлекает из базы данных. Новая функция HOTDESK_INFO() будет определена в файле func_odbc.conf следующим образом:

[INFO]

prefix=HOTDESK

dsn=asterisk

read=SELECT ${ARG1} FROM ast_hotdesk WHERE extension = '${ARG2}' Лишь несколько строк, а так много всего. Давайте быстренько рассмотрим все это, прежде чем двигаться дальше.

Прежде всего, параметр prefix необязательный. Если prefix не задан, Asterisk добавляет в имя функции (в данном случае INFO) префикс ODBC, то есть эта функция будет названа ODBC_INFO(). Такое имя не очень хорошо описывает назначение функции, поэтому полезно задавать префикс, который поможет связать ODBC-функции с задачами, ими выполняемыми. В данном случае мы выбрали имя HOTDESK, то есть данная специальная функция будет названа HOTDESK_INFO.

Атрибут dsn указывает Asterisk, какое из описанных в файле res_odbc. conf соединений использовать. Поскольку в res_odbc.conf может быть сконфигурировано несколько соединений, мы задаем здесь, какое именно должно использоваться. На рис. 12.1 показано отношение между различными настройками файлов и то, как они последовательно ссылаются друг на друга для соединения с базой данных.

Рис. 12.1. Отношения между func_odbc.conf, res_odbc.conf, /etc/odbc.ini (unixODBC) и соединение с базой данных

Затем описываем SQL-запрос с помощью атрибута read (чтение). Существует два разных формата вызова функций диалплана: один - для извлечения информации, а другой - для ее записи. Атрибут read используется, когда функция H0TDESK_INF0() вызывается в формате для извлечения данных (и можно выполнить отдельное SQL-выражение с атрибутом write (запись); формат для атрибута write обсуждается в данной главе несколько позже).

Для чтения значений из этой функции в диалплане используется следующий формат:

exten => s,n,Set(RETURNED_VALUE=${H0TDESK_INF0(status,1101)}) Это обеспечит возвращение значения, расположенного в столбце status (статус) базы данных, для которого значение столбца extension (добавочный номер) равно 1101. Переданные в функцию H0TDESK_INF0() значения столбца status и 1101 помещаются в SQL-запрос, заданный для атрибута read, и обозначаются как ${ARG1} и ${ARG2}. Если была передана третья опция, она будет доступна как ${ARG3}.

Убедитесь, что передаваемые данные достаточно уникальны и обеспечивают возвращение только одной строки. Если возвращается несколько строк, Asterisk будет видеть только первую из них. Для PostgreSQL можно ограничить возвращаемые данные одной строкой, добавив в конец SQL-запроса LIMIT 1, но это не очень хорошая практика и она не рекомендуется к применению. Чуть дальше в этом разделе мы увидим, как использовать PostgreSQL-функции LIMIT и OFFSET для перебора нескольких строк данных!

Использование функции ARRAY()

В нашем примере используется два отдельных вызова базы данных и получаемые в результате значения присваиваются двум переменным канала (${E}_STATUS и ${E}_PIN). Это было сделано с целью упростить пример:

exten => _110[1-5],n,Set(${E}_STATUS=${HOTDESK_INFO(status,${E})}) exten => _110[1-5],n,Set (${E}_PIN=${HOTDESK_INFO(pin,${E})})

В качестве альтернативы можно было бы возвращать несколько столбцов и сохранять их в разных переменных, используя функцию диалплана ARRAY() (массив). Если SQL-запрос в файле func_ odbc.conf определен так:

read=SELECT pin,status FROM ast_hotdesk WHERE extension = '${E}' с помощью функции ARRAY() можно в одном обращении к базе данных сохранять каждый столбец данных строки в собственной переменной:

exten => _110[1-5],n,Set(ARRAY(${E}_PIN,${E}_STATUS)=${HOTDES K_INFO(${E})})

После выполнения SQL-запроса возвращенное значение (если таковое имеется) присваивается переменной канала RETURNED_VALUE (возвращенное значение).

Итак, в первых двух строках следующего фрагмента кода мы передаем значение status и значение, содержащееся в переменной ${E} (например, 1101) в функцию HOTDESK_INFO(). Затем эти два значения замещаются в SQL-запросе на ${ARG1} и ${ARG2} соответственно, SQL-запрос выполняется, а возвращенное значение присваивается переменной канала ${E}_STATUS.

Итак, теперь закончим шаблонный добавочный номер:

exten => _110[1-5],n,Set(${E}_STATUS=${HOTDESK_INFO(status,${E})}) exten => _110[1-5],n,Set (${E}_PIN=${HOTDESK_INFO(pin,${E})}) exten => _110[1-5],n,GotoIf($[${ISNULL(${${E}_STATUS})}]? invalid_user,1) ; check if ${E}_STATUS is NULL

exten => _110[1-5],n,GotoIf($[${${E}_STATUS} = 1]?logout,1:login,1) Присвоив значение столбца status переменной ${E}_STATUS (если был набран добавочный номер 1101, имя переменной было бы 1101_STATUS), проверяем, было ли возвращено значение из базы данных (контроль ошибок). Для этой проверки используем функцию ISNULL(). Последняя строка фрагмента кода проверяет статус телефона, и, если в текущий момент он зарегистрирован, будет выполнен его выход из системы. Если он еще не зарегистрирован, управление перейдет к добавочному номеру login c приоритетом 1 в рамках того же контекста[117].

В следующей после 1.4 версии (в настоящее время готовящейся к выпуску) с выражениями, выполняемыми readsql, можно будет использовать переменную канала ${0DBCR0WS}. GotoIf() можно заменить примерно следующим:

exten => _110[1-5],n,GotoIf($[${0DBCR0WS} < 0]?invalid_user,1)

Добавочный номер login выполняет несколько начальных проверок, чтобы убедиться в достоверности введенного агентом кода. Мы предоставляем три попытки для ввода правильного пин-кода. Если все три ввода недействительны, вызов направляется на добавочный номер login_fail (неудачная регистрация) (который будет написан позже).

exten => login,1,No0p() ; задаем исходное значение счетчика

exten => login,n,Set(PIN_TRIES=0) ; задаем максимальное число попыток регистрации

exten => login,n,Set(MAX_PIN_TRIES=3)

exten => login,n(get_pin),No0p() ; увеличиваем счетчик попыток ввода пин-кода exten => login,n,Set(PIN_TRIES=$[${PIN_TRIES} + 1]) exten => login,n,Read(PIN_ENTERED|enter-password|${LEN (${${E}_PIN})}) exten => login,n,GotoIf($[${PIN_ENTERED} = ${${E}_PIN}]?valid_login,1) exten => login,n,Playback(invalid-pin)

exten => login,n,GotoIf($[${PIN_TRIES} <=${MAX_PIN_TRIES}]?get_pin:login_fail,1) Если введен соответствующий пин-код, проверяем регистрационное имя с помощью добавочного номера valid_login (действительное регистрационное имя). Сначала используем переменную CHANNEL (канал), чтобы выяснить, с какого телефона выполняется звонок. Обычно значение переменной имеет примерно такой вид: SIP/desk_1-ab4034c. Поэтому с помощью функции CUT() сначала отбрасываем часть строки SIP/, а оставшееся значение присваиваем переменной L0CATI0N (местоположение). Затем убираем часть строки - ab4034c, а оставшуюся строку, desk_1, присваиваем переменной L0CATI0N. exten => valid_login,1,No0p()

; отбрасываем технологию канала, а оставшуюся строку сохраняем в переменной ; L0CATI0N

exten => valid_login,n,Set(L0CATI0N=${CUT(CHANNEL,/,2)}) ; отбрасываем уникальный идентификатор

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату