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

Сейчас же я опишу, как произвести настройку OTRS в роли запрашивающего (requester). Когда в OTRS происходит какое-то событие и после этого идет обращение к внешней системе. А так же проблемы, с которыми столкнулся. Если заинтересовало, то прошу под кат.



Итак, установили мы замечательный OTRS, начали в нем работать. Но захотелось от системы большего. В нашем случае — интеграции с телеграм ботом. Кейс следующий: если приходит тикет от ВИП пользователя, то бот должен сразу проинформировать об этом ответственных лиц.

А для этого надо, чтобы система сама могла с ним общаться и сообщать о приходе таких тикетов.

В самом начале нам надо включить invoker. По умолчанию их всего два, и как сделать больше, я не разбирался. Для задачи и одного вполне хватает.

Для этого заходим в “Конфигурация системы” и далее ищем.
Edit Config Settings in GenericInterface -> GenericInterface::Invoker::ModuleRegistration



Просто включаем, ничего менять не надо.

Далее переходим в администрирование — > веб-сервисы.





Создаем новый веб сервис.
Вписываем название интерфейса
Выбираем сетевой транспорт HTTP::REST в блоке «OTRS как запрашивающий».
Жмем “Сохранить”.



После сохранения есть возможность выбрать Invoker и настроить транспорт.
Invoker у нас один, его и выбираем.



После добавления invoker вам сразу предложат его настроить.
Имя — тут все понятно
Дальше две мапы параметров. Я не уверен, что они в принципе работают, поэтому просто настроил пробрасывать как есть.
Триггер события — я выбрал по созданию тикета. Важно — не забудьте нажать плюсик. Только после этого ваш триггер добавится. Я минут 5 разбирался, почему после перезахода в настройки не видел своего триггера.

Триггер может быть синхронным и асинхронным. Если синхронный, то пока OTRS не получит ответ, вы не сможете дальше работать с тикетом. Асинхронный — OTRS отправит запрос в фоне.

Пример проблемы синхронных вызовов:
Настроили триггер на смену сервиса в тикете.
Открываем в тикете окно смены сервиса, меняем сервис.
Пока внешняя система не даст ответ, окно не закроется. Хотя должно закрываться сразу.



Далее настраиваем транспорт



Указываете адрес принимающей системы с портом. В следующей строке имя сервлета и TicketID. Согласно инструкции можно передавать еще и другие параметры от тикета, но у меня это не получилось. Поэтому все что мы имеем — номер тикета. Об этом чуть ниже.


На этом настройки закончены. При наступлении события наша внешняя система получила запрос.



За время настройки всплыло 2 момента:

  1. Если у вас не отправляются запросы и в логах “Got no TicketNumber”, то вам нужно на сервере найти файл Test.pm и везде поменять “TicketNumber” на “TicketID”. В моем случае он лежал тут — /opt/otrs/Kernel/GenericInterface/Invoker/Test.
    Спасибо этим ребятам за совет.
  2. OTRS по наступлению события отправляет только id тикета. Заявлено, что можно передавать и другие параметры. Однако это так и не удалось. В результате при наступлении события внешняя система получает TicketID, и по нему сама обращается в OTRS за полной информацией. Ребята с форума приблизительно так же и поступили.Это плодит дополнительные обращения, но в нашем случае не критично.

Если у кого-то есть интересные замечания, комментарии — welcome :)

Комментарии (4)


  1. eisaev
    04.09.2017 12:08

    OTRS по наступлению события отправляет только id тикета. Заявлено, что можно передавать и другие параметры. Однако это так и не удалось.

    Если посмотрите на функцию PrepareRequest в Test.pm, то можете увидеть какие именно параметры для запроса подготавливаются (по-умолчанию TicketNumberID, Action и SystemTime). Их можно использовать для запроса или дописать данную функцию для передачи нужным вам параметров.


    1. victor_2004 Автор
      04.09.2017 12:13

      Ребята с форума пробовали
      $ReturnData{Owner} = $Param{Data}=>{Owner};
      Я пробовал
      $ReturnData{CustomerID} = $Param{Data}=>{CustomerID};

      Увы не помогло ни мне, ни им.
      OTRS начал понимать, что CustomerID это переменная, но во внешнюю систему приходит пустое значение.


      1. eisaev
        04.09.2017 15:50

        Да. Судя по отладчику, invoker'у в принципе поступает только:

        $VAR1 = {
          'TicketID' => '14014'
        };


      1. eisaev
        04.09.2017 17:51

        В общем список полей для определённого события захардкожен. Например для событий по тикетам в Kernel/System/Ticket.pm. Вот например кусок для события TicketCreate:

            # trigger event
            $Self->EventHandler(
                Event => 'TicketCreate',
                Data  => {
                    TicketID => $TicketID,
                },
                UserID => $Param{UserID},
            );

        И здесь действительно только TicketID. А вот например для события TicketStateUpdate:
            # trigger event, OldTicketData is needed for escalation events
            $Self->EventHandler(
                Event => 'TicketStateUpdate',
                Data  => {
                    TicketID      => $Param{TicketID},
                    OldTicketData => \%Ticket,
                },
                UserID => $Param{UserID},
            );

        И здесь действительно уже кроме TicketID передаётся ещё и объект OldTicketData:
        $VAR1 = {
        
          'OldTicketData' => {
            'Age' => 21850,
            'ArchiveFlag' => 'n',
            'ChangeBy' => '20',
            'Changed' => '2017-09-04 17:44:18',
            'CreateBy' => '1',
            'CreateTimeUnix' => '1504514408',
            'Created' => '2017-09-04 11:40:08',
            'CustomerID' => '1024',
            'CustomerUserID' => 'tester',
            'EscalationDestinationDate' => '2017-09-04 15:40:08',
            'EscalationDestinationIn' => '2h 4m',
            'EscalationDestinationTime' => '1504528808',
            'EscalationResponseTime' => '0',
            'EscalationSolutionTime' => '1504528808',
            'EscalationTime' => -7450,
            'EscalationTimeWorkingTime' => '-7450',
            'EscalationUpdateTime' => '1504608258',
            'GroupID' => '2',
            'Lock' => 'lock',
            'LockID' => '2',
            'Owner' => 'isa',
            'OwnerID' => '20',
            'Priority' => '3 Обычный',
            'PriorityID' => '3',
            'Queue' => 'Корзина',
            'QueueID' => '10',
            'RealTillTimeNotUsed' => '0',
            'Responsible' => 'root@localhost',
            'ResponsibleID' => '1',
            'SLAID' => '',
            'ServiceID' => '',
            'SolutionTime' => -7450,
            'SolutionTimeDestinationDate' => '2017-09-04 15:40:08',
            'SolutionTimeDestinationTime' => '1504528808',
            'SolutionTimeEscalation' => 1,
            'SolutionTimeWorkingTime' => '-7450',
            'State' => 'open',
            'StateID' => '4',
            'StateType' => 'open',
            'TicketID' => '14014',
            'TicketNumber' => '20170904109849',
            'Title' => 'web service test',
            'Type' => 'default',
            'TypeID' => '1',
            'UnlockTimeout' => '1504536258',
            'UntilTime' => 0,
            'UpdateTime' => 72000,
            'UpdateTimeDestinationDate' => '2017-09-05 13:44:18',
            'UpdateTimeDestinationTime' => '1504608258',
            'UpdateTimeWorkingTime' => 14400
          },
          'TicketID' => '14014'
        };