Имея сравнительно небольшой опыт работы с PBX Asterisk и не имея практического опыта работы с OTRS, я некоторое время доводил интеграцию этих систем до ума. Первая документация по интеграции, которую мне доводилось прочесть, использовала старую версию OTRS и работала через SOAP интерфейс. Это конечно меня не радовало и я продолжил поиск уже по документации OTRS. Как оказалась данная система кроме SOAP имеет и REST API. Который я как раз и использовал. Я не стану рассказывать, как настраивается OTRS и Asterisk, и расскажу про сам процесс интеграции.
Со стороны Asterisk будет использоваться AGI интерфейс для работы с внешним скриптом, экстеншены будут написаны на AEL. Я не много пишу на ruby, по этому мой выбор пал именно на этот язык программирования.
И так, по техническому заданию, надо было сделать:
- Есть 2 вида клиентов: старые и новые. Разница между ними в том, что одни есть в базе OTRS, других нет. У клиента может быть несколько номеров телефонов, они разнесены по полям: Phone, Mobile, Fax.
- Есть агенты — это сотрудники, которые отвечают на телефонные звонки в офисе. Их внутренний номер телефона указан в поле Comment.
- Есть список телефонных номеров, с которых не создаются заявки в системе.
- 1 клиент — 1 заявка в сутки. Только сутки от 06:00 до 06:00 утра следующего дня. Но если ответил другой агент, то заявка должна создаться.
- Заявка создается после того, как агент закончит разговор.
- Если клиента нет в системе, то заявка создается без указания на клиента.
- Тема тикета: «Заявка создана по телефону: <номер телефона>»
- Если не существует агента, то тикет не создается.
- Тикет создается только при звонке с внешнего номера
Со стороны Asterisk необходимо понимать, в какой момент должен исполняться скрипт. Т.к. по условию, заявки должны были создаваться только при звонке с внешних номеров и только после того, как агент закончил разговор, один из вариантов выполнения agi-скрипта — это выполнять его в экстеншене 'h' для контекста входящих внешних звонков. И передавать в него единственный аргумент — внутренний номер агента, ответившего на звонок. И на данном этапе это единственное, что надо добавить в настройки Asterisk.
h => {
AGI(create_ticket.rb,${CONNECTEDLINE(num)});
HangUp();
};
AGI() — вызов функции AGI
create_ticket.rb — название скрипта
${CONNECTEDLINE(num)} — номер ответившего на звонок
Я не стал брать уже готовый гем для работы с AGI в ruby. Основная причина в том, что мне не нужен весь функционал. А тот функционал, что был нужен, я мог реализовать самостоятельно. Также OTRS была настроена на работу с базой данных MySQL по-этому необходимо установить гем mysql2:
gem install mysql2
Сам скрипт можно найти тут
Вначале надо настроить скрипт для работы в текущей среде:
# Имя хоста базы данных OTRS
DB_HOST = "<OTRS DB_IP>"
# Имя пользователя базы данных
DB_USER = "<OTRS DB_USER>"
# Название базы
DB_NAME = "<OTRS DB_NAME>"
# Пароль пользователя базы данных
DB_PASSWORD = "<OTRS DB_PASSWORD>"
# Имя агента OTRS
OTRS_USER = '<OTRS USER>'
# Пароль агента OTRS
OTRS_PASS = '<OTRS PASS>'
# URL OTRS для REST API, например http://localhost/otrs/nph-genericinterface.pl/Webservice
OTRS_REST_URL = '<OTRS REST URL>'
# URI для REST API, например /CreateTicket/New
OTRS_REST_URI_CREATE_TICKET = '<OTRS REST URI>'
# Номера телефонов, с которых будет игнорироваться создания тикетов
# указывать через пробел
IGNORE_PHONES = %w()
# полный путь до файла логов
LOG_FILE = '<OTRS LOGFILE>'
Есть один момент при создании заявки. Тело запроса выглядит вот так:
new_ticket = {
UserLogin: OTRS_USER,
Password: OTRS_PASS,
Ticket: {
Title: title,
Queue: 'Retail',
State: :new,
Priority: '3 normal',
CustomerUser: callerid,
CustomerId: @db_connector.current_customer.customer_id,
OwnerId: @db_connector.current_owner.user_id,
Owner: @db_connector.current_owner.login
},
Article: {
Subject: title,
Body: '--',
ContentType: 'text/plain; charset=utf8'
}
}
Queue — тип очереди в OTRS
Prority — стандартный приоритет тикета, здесь могут быть и другие типы приоритета: '1 very low', '3 normal', '4 high', '5 very high'
CustomerUser — имя пользователя клиента, это обязательное поле, и если пользователя клиента не существует, здесь будет '--'
CustomerId — клиент и это не числовое значение, судя по базе
OwnerId — id владельца заявки
Owner — имя пользователя владельца
В Article должны быть как минимум указаны данные 3 поля.
Если CustomerUser и CustomerId не совпадут для клиента, то заявка не заведется. При указании клиента нужны оба валидных параметра. Так же с OwnerId и Owner требуется оба поля с валидными данными. Кстати заявка будет создаваться от, указанных в настройках, пользователя OTRS.
Автор: Командир судна