Важно своевременно получать уведомления о том, что вы ответственный за ревью Merge Request, или что в вашем MR конфликт. Также важно оперативно замечать комментарии от коллег-ревьюверов.
В системах GitLab, BitBucket и GitHub уведомления реализуются чаще всего через email. Что на мой взгляд не удобно, и только создает помойку в рабочей почте, из-за чего можно пропустить важные письма.
Поэтому появилась идея написать приложение, которое будет отправлять уведомления о важных событиях из GitLab в Telegram.
Мне не удалось найти достойных аналогов. Есть похожие приложения, но обычно вас просят куда-то передать токен доступа от GitLab, или установить webhook на внешний сервис. Такие решение не допустимы в корпоративной разработке.
Мое решение сфокусировано на приватности и прозрачности. Код полностью открыт и доступен для изучения, а готовое приложение запускается у вас на ПК.
Disclamer
Проект был написан для личных нужд и находится в стадии разработки. Однако, основной функционал стабильно работает.
При обнаружении багов создавайте issues.
Свои идеи по улучшению можно предлагать в discussions.
Возможности
Коротко опишу имеющиеся на данный момент фичи. Они актуальны как для облачной версии GitLab, так и для self-host инстанса, который может стоять у вас на работе.
Уведомление о новых MegeRequest
Когда кто-то создает MR и назначает вас ответственным, то вам приходит уведомление. Из этого уведомления можно узнать название, короткое описание, теги, из какой ветки в какую открыт MR, и кто его автор.
Название MR кликабельное, позволяет сразу перейти к MR.

Планы на будущее:
1. Присылать уведомление, если в существующем MR вас сделали ответственным.
2. Уведомлять, если вас назначили ревьювером.
Уведомление о конфликте в вашем MergeRequests
Если в вашем MR возник конфликт, то вы будете своевременно оповещены. В этом уведомлении указывается название MR, проект и ветка.

Уведомление об обновлении MergeRequests
Когда кто-то делает коммиты в MR, в котором вы ответственный, вам сразу же приходит уведомление. Вы также сразу можете увидеть сколько задач еще не решено, и сколько конкретно ваших задач не было решено.

Планы на будущее:
1. Присылать отдельное уведомление, когда все назначенные вами задачи решены.
Уведомление об изменении статуса вашего MR
Когда статус вашего MR меняется, вы получаете уведомление.

Уведомление о новых задачах в ваших MR
В GitLab можно создавать не просто комментарии, а обсуждения (Discussions). Если кто-то создаст такое обсуждение в вашем MR, то вы сразу об этом узнаете.

Уведомление при упоминаниях в комментариях
Допустим, кто-то упомянул вас в MR, нужен ваш совет. Автор этого MR не вы, ответственным назначали тоже не вас. Даже в этом случае вам придет уведомление, так вы не пропустите сообщения с вашим упоминанием.

Уведомления при ответах в дискуссии, в которой вы писали
Важно оставаться в теме обсуждения, поэтому при появлении новых ответов в дискуссия, в которых вы участвовали, вы получите уведомление.
Оно будет содержать начальное сообщение обсуждения, ваше последнее сообщение в нем, а также два последних комментария. Таким образом вы будете понимать о чем идет речь.

Отвечайте на комментарии прямо из Telegram
Допустим вас упомянули в обсуждении, сразу знаете что ответить? Не тратьте время, отвечайте прямо из телеграм. Для этого просто ответьте на сообщение и напишите ваш комментарий.

В планах реализовать:
- Поддержку уведомлений для Issue.
- Гибкую настройку правил уведомлений. Вы сможете отписывать от уведомлений по конкретным проектам, MR. Фильтровать уведомления по тегам MR и многое другое.
- Меню в боте, которое позволит быстро получать информацию. Например, получить список MR, за которые вы отвечаете.
Как все устроено внутри?
Реализация простая, как доска. Раз в минуту по персональному токену из GitLab ходим в API с персональным токеном пользователя, и сохраняем данные по MR, Pipeline и прочем сущностям. Делается это чтобы знать, какие сущности новые, а какие уже были. Также загруженные данные испоьзуются для того, чтобы приложение могло отдавать какие-то данные не запрашивая GitLab, например бот может вернуть вам все MR, за которые вы отвечаете.
Так как все хостинги VCS оперируют в целом одинаковыми сущностями, было принято решение преобразовывать сущности GitLab в свою доменную модель. Таким образом, на основе этого проекта можно легко добавить поддержку другого хостинга VCS, достаточно написать конвертер его объектов в доменные сущности приложения.
Можно при желании также сделать уведомлятор в другие месенджеры. Это тоже вынесено в абстракции, нужно только реализовать отправление текстовой строки в конкретный месенджер.
Модули
На данный момент проект состоит из 6 модулей:
- bot-context: Содержит доменные сущности, а также интерфейсы репозиториев и сервисов.
- bot-core: Содержит реализацию интерфейсов сервисов из bot-context. А также классы для конфигурации приложения.
- bot-data: Содержит реализацию интерфейсов репозиториев из bot-context.
- gitlab-sdk: Содержит классы сопостовимые с JSON ответами GitLab.
- telegram-bot: Отвечает за настройку и взаимодействие с Telegram
- gitlab-app: Объединяет все модули и запускает приложение
GitLab-sdk
Содержит классы, соответствующие JSON ответам GitLab API. Все классы из этого модуля оканчиваются на Json: NoteJson, CommitJson и так далее.
Bot-context
Содержит интерфейсы сервисов и репозиториев, а также доменные сущности приложения.
Так как GitLab, BitBucket и GitHub очень похожи, то имело смысл сделать асбтракции над их сущностями. То есть, я выделил общие черты мержреквсеста в трех этих системах, и создал свой класс MergeRequest. Вся бизнес логика работает с такими абстракциями, что позволяет легко адаптировать бота под любую систему.
Помимо сущностей для сохранения в бд, есть еще классы уведомлений. Когда нужно отправить какое-то уведомление пользователю, необходимо вызвать метод send()
сервиса NotifyService
.
public interface NotifyService {
<T extends Notify> void send(T notify);
}
Все классы уведомлений должны реализовать интерфейс Notify
, один метод которого отвечает за генерацию текстового сообщения, которое будет отправлено пользователю.
public interface Notify {
String generateMessage(AppSettingService appSettingService);
}
AppSettingService
передается, чтобы реализовать мультиязычное приложение.
Bot-core
Содержит основную логику работы приложения.
Классы Parser
отвечают за запросы к GitLab API. Полученные классы мы преобразуем в наши доменные сущности. Допустим MergeRequestParser
запрашивает объекты MergeRequestJson
и преобразует их в наш MergeRequest
.
Таких парсеров всего 4: DiscussionParser
, PipelineParser
, ProjectParser
, MergeRequestParser
. Каждый отвечает за извлечение данных и преобразование в наши сущности.
Остальные сервисы в этом модуле отвечают за CRUD и простые операции фильтрации.
Telegram-Bot
Логика этого модуля похожа на абстракции над хостингами VCS. Чтобы добавить поддержку другого мессенджера, необходимо создать новый модуль и реализовать интерфейс MessageSendService
@FunctionalInterface
public interface MessageSendService {
void send(@NonNull Notify notify);
}
Этот интерфейс отвечает непосредственно за отправку.
Gitlab-app
Модуль, который собирает все модули вместе, создает конфигурациионные бины для SpringBoot, и запускает приложение.
Запуск бота
Какие варианты запуска поддерживаются:
- Склонировать проект и запустить его прямо в Idea
- Скачать Jar-файл релиза с GitHub и запустить его.
- Запустить образ Docker
- Запустить Docker Compose
Но сперва необходимо создать бота в Telegram, который будет отправлять вам уведомления
- Создаем бота в Telegram, который будет посылать вам уведомления. Делается это тут
- После создания вы получите токен, сохраните его. Пример:
34534050345:FlfrleflerferfRE-ergerFLREF9ERF-NGjM
- Теперь необходимо получить персональный токен в вашем GitLab. В правом верхнем углу нажмите на иконку своего аккаунта, далее Settings –> Personal Access Tokens. Укажите Scopes: api и нажмите Create a token.
Конфигурация
Несмотря на то, какой вариант запуска вы виберете, необходимо будет указать следующие переменные.
TELEGRAM_BOT_TOKEN
— токен, который вы получили при создание бота.TELEGRAM_BOT_USERNAME
— название, которое вы дали боту. Оканчивается на bot.GITLAB_PERSONAL_TOKEN
— токен, который вы получили в GitLabTELEGRAM_PERSON_ID
— ваш id в telegram, можно узнать тут.GITLAB_URL
— url на gitlab. Локальный или облачный.DATASOURCE_URL
— ссылка на базу данных Postgres, в следующем формате: jdbc:postgresql://localhost:5432/gitlab_botDATASOURCE_USERNAME
— пользователь БДDATASOURCE_PASSWORD
— пароль от БД
Запускаем как Jar
Скачать актуальный jar-файл всегда можно на странице резилов GitHub.
java -DTELEGRAM_BOT_USERNAME=value \
-DTELEGRAM_BOT_TOKEN=value \
-DTELEGRAM_PERSON_ID=value \
-DDATASOURCE_URL=value \
-DDATASOURCE_PASSWORD=value \
-DDATASOURCE_USERNAME=value \
-DGITLAB_PERSONAL_TOKEN=value \
-DGITLAB_URL=value \
-jar gitlab-notification.jar
Docker
Команда для запуска выглядит следующим образом:
sudo docker run --name gitlab-notify \
--env TELEGRAM_BOT_TOKEN=value \
--env TELEGRAM_BOT_USERNAME=value \
--env GITLAB_PERSONAL_TOKEN=value \
--env TELEGRAM_PERSON_ID=value \
--env GITLAB_URL=value \
--env DATASOURCE_URL=jdbc:postgresql://localhost:5432/gitlab_bot \
--env DATASOURCE_USERNAME=postgres \
--env DATASOURCE_PASSWORD=value \
--network="host" upagge/gitlab-telegram-notify:latest
Заключение
В этой статье, я рассказал о своем пет-проекте, разобрал его основные модули и некоторые аспекты реализхации. Также показал, как можно запустить приложение, используя различные способы,
Надеюсь этот бот будет полезным не только для меня, но и избавит вас от постоянных email уведомлений от GitLab.