OTRS ( Open-source Ticket Request System) — открытая система обработки заявок. OTRS позволяет организациям, занимающимся технической поддержкой каких-либо проектов, совместно работать над решением проблем пользователей. Программа написана на языке Perl, поддерживает множество СУБД (MySQL, PostgreSQL и т. д.), может интегрироваться с LDAP каталогом, распространяется по лицензии — AGPL версии 3. Программный продукт протестирован на таких системах как: Linux, Solaris, AIX, FreeBSD, OpenBSD, Mac OS X и Windows.

Системы обработки заявок, такие как OTRS, обрабатывают заявки как обыкновенные почтовые сообщения (email). Когда клиент посылает по почте запрос, система создает новую заявку. Клиентам так-же доступен веб-интерфейс для создания новых заявок, проверки состояния существующих, написания ответов на старые заявки а также поиска их собственных заявок. Для интеграции собственных дополнений и приложений существует — OTRS API. Воспользуемся предоставленными возможностями для формирования заявки по телефону.

Задача: При входящем соединении на номер HelpDesk, происходит формирование заявки ( на основании определившегося номера) и вызов передается оператору. При ответе оператор открывая интерфейс работы с заявками уже имеет новую сформированную заявку и ему только необходимо ввести содержание.

Реализация: На стороне OTRS.

Для формирования заявки будем использовать протокол SOAP. SOAP ( Simple Object Access Protocol — простой протокол доступа к объектам) — протокол обмена структурированными сообщениями в распределённой вычислительной среде. Первоначально SOAP предназначался в основном для реализации удалённого вызова процедур (RPC). Сейчас протокол используется для обмена произвольными сообщениями в формате XML, а не только для вызова процедур. Официальная спецификация последней версии 1.2 протокола никак не расшифровывает название SOAP. SOAP является расширением протокола XML-RPC. SOAP может использоваться с любым протоколом прикладного уровня: SMTP, FTP, HTTP, HTTPS и др. Однако его взаимодействие с каждым из этих протоколов имеет свои особенности, которые должны быть определены отдельно. Чаще всего SOAP используется поверх HTTP. SOAP является одним из стандартов, на которых базируются технологии веб-служб.

Для использования данной возможности, необходимо задать имя пользователя и пароль. Следуем Администрирование -> Конфигурация системы. Выбираем модуль Core::SOAP и подтверждаем введенные данные.

Дальнейшие наши действия будут проходить на стороне Asterisk. Предположим номер на который приходит входящий вызов HelpDesk — 4509, а номер оператора — 4507. Отредактируем файл конфигурации vim /etc/asterisk/extensions_custom.conf следующим образом.

[otrs]

Файл — zayav.agi, обычный скрипт AGI, с двумя добавленными последними строками, которыми мы получаем и передаем номер позвонившего абонента в скрипт формирования заявки (my $cid = $AGI{‘callerid’};system( «/opt/otrs/scripts/rpc_ast.pl $cid»);).

#!/usr/bin/perl
use strict;
$|=1;
# Setup some variables
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
while() {
        chomp;
        last unless length($_);
        if (/^agi_(\w+)\:\s+(.*)$/) {
                $AGI{$1} = $2;
        }
}
sub checkresult {
        my ($res) = @_;
        my $retval;
        $tests++;
        chomp $res;
        if ($res =~ /^200/) {
                $res =~ /result=(-?\d+)/;
                if (!length($1)) {
                        print STDERR "FAIL ($res)\n";
                        $fail++;
                } else {
                        print STDERR "PASS ($1)\n";
                        $pass++;
                }
        } else {
                print STDERR "FAIL (unexpected result '$res')\n";
                $fail++;
        }
}
my $result = ;
&checkresult($result);
my $cid = $AGI{'callerid'};
system( "/opt/otrs/scripts/rpc_ast.pl $cid");
exit 0;

Скрипт — /opt/otrs/scripts/rpc_ast.pl выполняет две задачи. Первая — извлекает из базы OTRS на основании определенного номера телефона — имя пользователя и его ID (Имя пользователя и пароль для подключения к базе OTRS приведены по умолчанию). Необходимые данные находятся в таблице customer_user.

Подразумевается что данный пользователь есть в Базе OTRS и имеет необходимые атрибуты (в частности номер телефона).

$database="otrs";
$hostname="localhost";
$user="otrs";
$password='hot';
          $myquery= "SELECT login,customer_id  FROM customer_user where phone='$cid'";
          $dbh = DBI->connect("DBI:mysql:database=$database;host=$hostname",
                    $user, $password) || die print "Can't connect";
          $sth = $dbh->prepare( $myquery )
                 || die "Can't prepare statement: $DBI::errstr";
          $sth->execute;
              while ( @result = $sth->fetchrow_array)
             {
             $rez1=$result[0];
             $rez2=$result[1];
             }
$dbh->disconnect;

Вторая — формирует заявку и ее атрибуты.

 
use strict;
use warnings;
use SOAP::Lite( 'autodispatch', proxy => 'http://127.0.0.1/otrs/rpc.pl' );
my $User = 'admin';
my $Pw   = 'user';
my $RPC = Core->new();
my $TicketNumber = $RPC->Dispatch( $User, $Pw, 'TicketObject', 'TicketCreateNumber' );
my %Ticket = $RPC->Dispatch( $User, $Pw, 'TicketObject', 'TicketGet', TicketID => 1 );
my %TicketData = (
    Title        => "Заявка с номера $cid",
    Queue        => 'Raw',
    Lock         => 'unlock',
    Priority     => '2 low',
    State        => 'new',
    CustomerID   => $rez2,
    CustomerUser => $rez1,
    OwnerID      => 2,
    UserID       => 'admin',
);
my $TicketID = $RPC->Dispatch( $User, $Pw, 'TicketObject', 'TicketCreate', %TicketData => 1 )
    || die "Failed to create ticket: $!";
my $ArticleID =$RPC->Dispatch($User, $Pw, 'TicketObject', 'ArticleCreate',
        TicketID         => $TicketID,
        ArticleType      => 'webrequest',                  
        SenderType       => 'customer',                          
        From             => '
 you@firma.com',  
        To               => '
 firma@firma.com', 
        Subject          => "Заявка с номера $cid",         
        Body             => "Заявка с номера $cid .... получите",               
        ContentType      => 'text/plain',
        Charset          => 'ISO-8859-1',
        HistoryType      => 'WebRequestCustomer',                   
        HistoryComment   => '....Текст.....',
        UserID           => 2,
        Loop             => 0,                    
    );
exit 0;

Проверяем работу — пробуем набрать на настроенный для выполнения agi скрипта номер. Для контроля выполнения, включим режим отладки — agi set debug on.

AGI Tx >> agi_channel: SIP/84956693308-0000039a
AGI Tx >> agi_language: en
AGI Tx >> agi_type: SIP
AGI Tx >> agi_uniqueid: 1314075508.1094
AGI Tx >> agi_version: 1.6.2.17.3
AGI Tx >> agi_callerid: 89161229624
AGI Tx >> agi_calleridname: 89161229624
AGI Tx >> agi_callingpres: 0
AGI Tx >> agi_callingani2: 0
AGI Tx >> agi_callington: 0
AGI Tx >> agi_callingtns: 1
AGI Tx >> agi_dnid: 84956693308
AGI Tx >> agi_rdnis: unknown
AGI Tx >> agi_context: otrs
AGI Tx >> agi_extension: 4509
AGI Tx >> agi_priority: 2
AGI Tx >> agi_enhanced: 0.0
AGI Tx >> agi_accountcode:
AGI Tx >> agi_threadid: -1251619952
AGI Tx >>
AGI Tx >> 200 result=0 endpos=3520
    -- AGI Script zayav.agi completed, returning 0

и — voilà.

заявка сформирована. Отвечаем на входящий вызов, открываем сформированную заявку и вводим «жалобу» клиента. Конечно рекомендуется использовать несколько больше атрибутов из базы клиента для формирования более «правильной» заявки.