Выбирая замену, используемой у нас системы обмена сообщениями, наткнулся на описание Mattermost, и решил попробовать. Одним из плюсов, описываемой системы, является простая интеграция со сторонними сервисами, так называемые "хуки" (outgoing и incoming hooks). Вот про настройку взаимодействия через хуки с внешними системами и будет данная статья (в нашем конкретном случае это zabbix и glpi).
Часть первая. Интеграция с GLPI
Так как мы, в своей работе, для учета оборудования, программного обеспечения, соединений, регистрации обращений в техподдержку используем GLPI, то логично было-бы организовать возможность для пользователей отправлять заявки в ТП из mattermost.
API
Для интеграции с внешними сервисами у GLPI есть http rest api. Документация по нему доступна в установленной системе по ссылке http://glpi/apirest.php/#glossary (где "glpi" адрес вашего сервера).
Слегка подумав над задачей, было решено алгоритм обмена реализовать на php, в пользу данного решения говорит то факт, что php уже установлен в системе и скрипт был органично вписан в glpi и доступен по адресу http://glpi/mm.php. Получился, своего рода, "прокси", который принимает запрос от mattermost, преобразует в нужный формат и отправляет GLPI. Все http-запросы передаются в JSON-формате.
Процедура работы состоит из 5-ти частей:
- Получение запроса от mattermost
- Инициализация сессии в glpi
- Получение данных из запроса
- Отправка данных в glpi
- Закрытие сессии
Перед тем как приступить к описанию кода срипта, проведём подготовительную работу как в mattermost так и в glpi.
GLPI
- Cоздадим пользователя helpdesk, от имени которого, будут создаваться запросы, и зайдя в настройки этого пользователя сгенерируем токены:

Тот, что обведен красным, будет user_token. - В настройках системы необходимо добавить клиента для взаимодействия с API. Для этого идём в "Настройки"->"Общие"->"API" и нажав кнопку "Добавить клиента", добавляем запись и генерируем токен (app_token)

- Для идентификации источника запросов в системе, добавим запись в справочник "Источники запросов" и зайдя в, только что, добавленную запись запомним его id (обведено красным)

На этом настройка АПИ в GLPI закончена.
Mattermost
В меню клиента Mattermost идём в "Inegration"->"Outgoing Webhooks" жмем "Add" и добавлем запись. На скрине я подчеркнул значимые поля. Тут следует сделать отступление: в mattermost "спусковым крючком" для запуска процедуры отправки запроса служит слово или фраза, которая, будучи указанной в начале сообщения, собственно, и запускает процесс. В нащем случае слово-тригер — "112" (тут прямая ассоциация с МЧС).

Имя пользователя по умолчанию и ссылку на аватарку можно добавить (а можно не добавлять), так как эти параметры будут переданы в запросе. Но для того, чтобы mattermost смог обрабатывать данные параметры, в настройках сервера надо поменять пару опций в файле /opt/mattermost/config/config.json
"EnablePostUsernameOverride": true, "EnablePostIconOverride": true,
На этом настройка окончена. Настало время перейти к написанию кода. Скрипт скопирован в корневой каталог с файлами glpi, в моём случае это /var/www/html/glpi/mm.php
<?php # GLPI токены сгенерированные в настройках $app_token = '7uizyyildM71x84j1UxeABXTuCHdPoLRW45Tx2wG'; $user_app_token ='dZdCqc10Xhb1TxCT4OsXp8qqDSEqILASf2wZot0w'; # Тип источника запроса (значение из справочника, которое запомнили чуть раньше) $requesttypes_id = '7'; # Код типа запроса GLPI (1 - Инцидент, 2 - Запрос) $type = '1'; # Принимает запрос и декодируем данные $postData = file_get_contents('php://input'); $data = json_decode($postData, true); # Разбор json от MatterMost. Если эти данные нужны соответствующую строку # можно раскоментировать и использовать перменную ниже по коду #$message_text = $data["text"]; #$user_name = $data["user_name"]; #$user_id = $data["user_id"]; #$channel_name = $data["channel_name"]; #$channel_id = $data["channel_id"]; #$team_domain = $data["team_domain"]; #$team_id = $data["team_id"]; #$post_id = $data["post_id"]; # обрезаем "112" от сообщения, точнее обрезаем первые 4 символа. $message_text = substr($data["text"],4); # Ответ на POST запрос, который будет выведен пользователю в mattermost #HTTP/1.1 200 OK header('Content-Type: application/json'); $reply = array( 'response_type' => 'comment', 'text'=> 'Ваш запрос передан в службу технической поддержки' ); echo json_encode($reply); # Инициируем пользовательскую сессию в glpi # тут нам и понадобятся ранее сгенерированные токены # данный запрос вернёт идентификатор сессии для дальнейшей работы if( $curl = curl_init() ) { curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: user_token '.$user_app_token, 'App-Token: '.$app_token)); curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/initSession'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $out = curl_exec($curl); $session = json_decode($out, true); $session_token = $session["session_token"]; #echo $session_token; curl_close($curl); } # подготовим текст для запроса создания заявки $json = array( 'input'=> array( 'name'=>'Заявка от '.$data["user_name"], 'requesttypes_id'=>$requesttypes_id, 'content'=>$message_text, 'type'=>$type ) ); # Отправим запрос if( $curl = curl_init() ) { curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'App-Token: '.$app_token, 'Session-token: '.$session_token)); curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/Ticket'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($json)); $out = curl_exec($curl); curl_close($curl); } # Закроем сессию if( $curl = curl_init() ) { curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'App-Token: '.$app_token, 'Session-token: '.$session_token)); curl_setopt($curl, CURLOPT_URL, 'http://glpi/apirest.php/killSession'); curl_setopt($curl, CURLOPT_POST, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $out = curl_exec($curl); curl_close($curl); } ?>
Результатом работы данного скрипта будет добавленный запрос в системе регистрации инцидентов в GLPI. В картинках это выглядит следующим образом:
Пишем сообщение в mattermost:

Идём в GLPI "Поддержка"->"Заявки" и в списке должно появится новое сообщение:

Ткнув на заголовок сообщения, откроется более подробная информация (красным обведены поля, значения которых передаются в скрипте)

На этом настройку отправки сообщений в GLPI из Mattermost, можно считать завершенной. Поработав немного над кодом, ничто не помешает реализовать изменение типа запроса (инцидент или заявка).
