From e5727f2b3021e13f317214f46343a32960449367 Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Tue, 3 Sep 2024 23:21:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=93=D1=80=D1=83=D0=BF=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=83=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BE=20=D0=BF=D0=B0=D0=B9=D0=BF=D0=BB?= =?UTF-8?q?=D0=B0=D0=B9=D0=BD=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gitlab/context/domain/PipelineStatus.java | 2 +- .../NewMergeRequestGroupPersonalNotify.java | 4 +- .../group/pipeline/PipelineGroupNotify.java | 37 +++++++ .../pipeline/PipelinePersonalNotify.java | 9 +- .../context/repository/PersonRepository.java | 4 +- .../gitlab/context/service/PersonService.java | 3 + .../gitlab/core/handler/PipelineHandler.java | 103 ++++++++++++++---- .../core/service/PersonServiceImpl.java | 8 +- .../data/impl/PersonRepositoryImpl.java | 7 +- .../gitlab/data/jpa/PersonJpaRepository.java | 1 + .../notify/PipelineNotifyGenerator.java | 16 +-- .../group/PipelineGroupNotifyGenerator.java | 49 +++++++++ 12 files changed, 197 insertions(+), 46 deletions(-) create mode 100644 bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/pipeline/PipelineGroupNotify.java create mode 100644 telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/group/PipelineGroupNotifyGenerator.java diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/PipelineStatus.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/PipelineStatus.java index 65a3df1..b11485e 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/PipelineStatus.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/PipelineStatus.java @@ -21,7 +21,7 @@ public enum PipelineStatus { SKIPPED("\uD83D\uDD18"), MANUAL("\uD83D\uDD79"), SCHEDULED("\uD83D\uDD52"), - NULL("\uD83C\uDD95"); + NEW("\uD83C\uDD95"); private final String icon; diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/mr/NewMergeRequestGroupPersonalNotify.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/mr/NewMergeRequestGroupPersonalNotify.java index 9ba6c77..e783bb2 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/mr/NewMergeRequestGroupPersonalNotify.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/mr/NewMergeRequestGroupPersonalNotify.java @@ -8,11 +8,13 @@ import lombok.Getter; import java.util.Map; +import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupPersonalNotifyFields.CLASS_NAME; + @Getter @FieldNames public class NewMergeRequestGroupPersonalNotify implements GroupNotify { - public static final String TYPE = "NewMergeRequestGroupNotify"; + public static final String TYPE = CLASS_NAME; protected final Long mrId; protected final String projectName; diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/pipeline/PipelineGroupNotify.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/pipeline/PipelineGroupNotify.java new file mode 100644 index 0000000..a440f8e --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/group/pipeline/PipelineGroupNotify.java @@ -0,0 +1,37 @@ +package dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline; + +import dev.struchkov.bot.gitlab.context.domain.PipelineStatus; +import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify; +import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames; +import lombok.Builder; +import lombok.Getter; + +@Getter +@FieldNames +public class PipelineGroupNotify implements GroupNotify { + + public static final String TYPE = "PipelineGroupNotify"; + + private final String projectName; + private final String refName; + private final PipelineStatus oldStatus; + private final PipelineStatus newStatus; + private final String webUrl; + private final String ownerTelegramUsername; + + @Builder + public PipelineGroupNotify(String projectName, String refName, PipelineStatus oldStatus, PipelineStatus newStatus, String webUrl, String ownerTelegramUsername) { + this.projectName = projectName; + this.refName = refName; + this.oldStatus = oldStatus; + this.newStatus = newStatus; + this.webUrl = webUrl; + this.ownerTelegramUsername = ownerTelegramUsername; + } + + @Override + public String getType() { + return TYPE; + } + +} diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pipeline/PipelinePersonalNotify.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pipeline/PipelinePersonalNotify.java index d7cdf5b..7a12813 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pipeline/PipelinePersonalNotify.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pipeline/PipelinePersonalNotify.java @@ -18,8 +18,7 @@ public final class PipelinePersonalNotify implements PersonalNotify { public static final String TYPE = CLASS_NAME; - private final Long projectId; - private final Long pipelineId; + private final String projectName; private final String refName; private final PipelineStatus oldStatus; private final PipelineStatus newStatus; @@ -27,15 +26,13 @@ public final class PipelinePersonalNotify implements PersonalNotify { @Builder public PipelinePersonalNotify( - Long projectId, - Long pipelineId, + String projectName, String refName, PipelineStatus oldStatus, PipelineStatus newStatus, String webUrl ) { - this.projectId = projectId; - this.pipelineId = pipelineId; + this.projectName = projectName; this.refName = refName; this.oldStatus = oldStatus; this.newStatus = newStatus; diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/repository/PersonRepository.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/repository/PersonRepository.java index 33c0834..29db27a 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/repository/PersonRepository.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/repository/PersonRepository.java @@ -18,6 +18,8 @@ public interface PersonRepository { List findAllById(Set personIds); - List getAllTelegramInfoByIds(Set personIds); + Optional findTelegramInfoById(Long personId); + + List findAllTelegramInfoByIds(Set personIds); } diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/PersonService.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/PersonService.java index ff9d882..86e693e 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/PersonService.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/PersonService.java @@ -6,6 +6,7 @@ import lombok.NonNull; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -21,6 +22,8 @@ public interface PersonService { List createAll(List newPersons); + Optional getTelegramUsernamesByPersonIds(Long personId); + Map getTelegramUsernamesByPersonIds(Set personIds); } diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/handler/PipelineHandler.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/handler/PipelineHandler.java index 92d20ef..e284663 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/handler/PipelineHandler.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/handler/PipelineHandler.java @@ -6,8 +6,12 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Person; import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline; import dev.struchkov.bot.gitlab.context.domain.event.NewPipelineEvent; import dev.struchkov.bot.gitlab.context.domain.event.UpdatePipelineEvent; +import dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline.PipelineGroupNotify; import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotify; import dev.struchkov.bot.gitlab.context.service.NotifyService; +import dev.struchkov.bot.gitlab.context.service.PersonService; +import dev.struchkov.bot.gitlab.context.service.ProjectService; +import dev.struchkov.haiti.utils.Strings; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; @@ -15,6 +19,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.Objects; +import java.util.Optional; import java.util.Set; import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CANCELED; @@ -30,24 +35,48 @@ public class PipelineHandler { // Статусы пайплайнов, о которых нужно уведомить private static final Set notificationStatus = Set.of(FAILED, SUCCESS, CANCELED, SKIPPED); + private final PersonService personService; private final PersonInformation personInformation; private final NotifyService notifyService; + private final ProjectService projectService; @EventListener public void newPipelineHandle(NewPipelineEvent event) { final Pipeline pipeline = event.getPipeline(); - if (isNeedNotifyNewPipeline(pipeline)) { - notifyService.send( - PipelinePersonalNotify.builder() - .projectId(pipeline.getProjectId()) - .newStatus(pipeline.getStatus()) - .pipelineId(pipeline.getId()) - .refName(pipeline.getRef()) - .webUrl(pipeline.getWebUrl()) - .oldStatus(PipelineStatus.NULL) - .build() - ); + + final Optional optProjectName = projectService.getProjectNameById(pipeline.getProjectId()) + .map(Strings::escapeMarkdown); + + if (isNeedPersonalNotifyPipeline(pipeline)) { + final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder() + .newStatus(pipeline.getStatus()) + .refName(pipeline.getRef()) + .webUrl(pipeline.getWebUrl()) + .oldStatus(PipelineStatus.NEW); + + optProjectName.ifPresent(builder::projectName); + + notifyService.send(builder.build()); } + + if (isNeedPersonalGroupPipeline(pipeline)) { + final Optional optTelegramUsername = personService.getTelegramUsernamesByPersonIds(pipeline.getPerson().getId()); + if (optTelegramUsername.isPresent()) { + final String telegramUsername = optTelegramUsername.get(); + + final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder() + .newStatus(pipeline.getStatus()) + .refName(pipeline.getRef()) + .webUrl(pipeline.getWebUrl()) + .oldStatus(PipelineStatus.NEW) + .ownerTelegramUsername(telegramUsername); + + optProjectName.ifPresent(builder::projectName); + + notifyService.send(builder.build()); + } + } + } @EventListener @@ -55,22 +84,43 @@ public class PipelineHandler { final Pipeline oldPipeline = event.getOldPipeline(); final Pipeline newPipeline = event.getNewPipeline(); if (!Objects.equals(oldPipeline.getUpdated(), newPipeline.getUpdated())) { - if (isNeedNotifyNewPipeline(newPipeline)) { - notifyService.send( - PipelinePersonalNotify.builder() - .projectId(newPipeline.getProjectId()) - .newStatus(newPipeline.getStatus()) - .pipelineId(newPipeline.getId()) - .refName(newPipeline.getRef()) - .webUrl(newPipeline.getWebUrl()) - .oldStatus(oldPipeline.getStatus()) - .build() - ); + final Optional optProjectName = projectService.getProjectNameById(newPipeline.getProjectId()) + .map(Strings::escapeMarkdown); + + if (isNeedPersonalNotifyPipeline(newPipeline)) { + final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder() + .newStatus(newPipeline.getStatus()) + .refName(newPipeline.getRef()) + .webUrl(newPipeline.getWebUrl()) + .oldStatus(oldPipeline.getStatus()); + + optProjectName.ifPresent(builder::projectName); + + notifyService.send(builder.build()); } + + if (isNeedPersonalGroupPipeline(newPipeline)) { + final Optional optTelegramUsername = personService.getTelegramUsernamesByPersonIds(newPipeline.getPerson().getId()); + if (optTelegramUsername.isEmpty()) { + final String telegramUsername = optTelegramUsername.get(); + + final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder() + .newStatus(newPipeline.getStatus()) + .refName(newPipeline.getRef()) + .webUrl(newPipeline.getWebUrl()) + .oldStatus(oldPipeline.getStatus()) + .ownerTelegramUsername(telegramUsername); + + optProjectName.ifPresent(builder::projectName); + + notifyService.send(builder.build()); + } + } + } } - private boolean isNeedNotifyNewPipeline(@NonNull Pipeline pipeline) { + private boolean isNeedPersonalNotifyPipeline(@NonNull Pipeline pipeline) { final Person personPipelineCreator = pipeline.getPerson(); return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления && checkNotNull(personPipelineCreator) // Создатель пайплайна не null @@ -78,4 +128,11 @@ public class PipelineHandler { && LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад } + private boolean isNeedPersonalGroupPipeline(@NonNull Pipeline pipeline) { + final Person personPipelineCreator = pipeline.getPerson(); + return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления + && checkNotNull(personPipelineCreator) // Создатель пайплайна не null + && LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад + } + } diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/PersonServiceImpl.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/PersonServiceImpl.java index 96b0df7..4f4e514 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/PersonServiceImpl.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/PersonServiceImpl.java @@ -12,6 +12,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -61,9 +62,14 @@ public class PersonServiceImpl implements PersonService { .toList(); } + @Override + public Optional getTelegramUsernamesByPersonIds(Long personId) { + return repository.findTelegramInfoById(personId).map(PersonTelegram::getTelegramUserName); + } + @Override public Map getTelegramUsernamesByPersonIds(Set personIds) { - return repository.getAllTelegramInfoByIds(personIds).stream() + return repository.findAllTelegramInfoByIds(personIds).stream() .collect(Collectors.toMap(PersonTelegram::getId, PersonTelegram::getTelegramUserName)); } diff --git a/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/impl/PersonRepositoryImpl.java b/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/impl/PersonRepositoryImpl.java index 13d6889..161b0b2 100644 --- a/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/impl/PersonRepositoryImpl.java +++ b/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/impl/PersonRepositoryImpl.java @@ -38,7 +38,12 @@ public class PersonRepositoryImpl implements PersonRepository { } @Override - public List getAllTelegramInfoByIds(Set personIds) { + public Optional findTelegramInfoById(Long personId) { + return jpaTelegramRepository.findById(personId); + } + + @Override + public List findAllTelegramInfoByIds(Set personIds) { return jpaTelegramRepository.findAllById(personIds); } diff --git a/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/jpa/PersonJpaRepository.java b/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/jpa/PersonJpaRepository.java index 6893688..d53f305 100644 --- a/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/jpa/PersonJpaRepository.java +++ b/bot-data/src/main/java/dev/struchkov/bot/gitlab/data/jpa/PersonJpaRepository.java @@ -8,4 +8,5 @@ import org.springframework.data.jpa.repository.JpaRepository; */ public interface PersonJpaRepository extends JpaRepository { + } diff --git a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/PipelineNotifyGenerator.java b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/PipelineNotifyGenerator.java index 73254c7..70d439c 100644 --- a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/PipelineNotifyGenerator.java +++ b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/PipelineNotifyGenerator.java @@ -1,41 +1,33 @@ package dev.struchkov.bot.gitlab.telegram.service.notify; import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotify; -import dev.struchkov.bot.gitlab.context.service.ProjectService; import dev.struchkov.bot.gitlab.context.utils.Icons; import dev.struchkov.godfather.simple.domain.BoxAnswer; -import dev.struchkov.haiti.utils.Strings; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import java.util.Optional; - import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; import static dev.struchkov.godfather.telegram.domain.keyboard.SimpleKeyBoardLine.keyBoardLine; import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; import static dev.struchkov.godfather.telegram.domain.keyboard.button.UrlButton.urlButton; import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN; +import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; @Service @RequiredArgsConstructor public class PipelineNotifyGenerator implements NotifyBoxAnswerGenerator { - private final ProjectService projectService; - @Override public BoxAnswer generate(PipelinePersonalNotify notify) { - final StringBuilder builder = new StringBuilder(Icons.BUILD).append(" *New pipeline | ").append(notify.getPipelineId()).append("*"); + final StringBuilder builder = new StringBuilder(Icons.BUILD).append(" *New pipeline* "); builder .append(Icons.HR); - final Optional optProjectName = projectService.getProjectNameById(notify.getProjectId()) - .map(Strings::escapeMarkdown); - if (optProjectName.isPresent()) { - final String projectName = optProjectName.get(); - builder.append(Icons.PROJECT).append(": ").append(projectName).append("\n"); + if (checkNotEmpty(notify.getProjectName())) { + builder.append(Icons.PROJECT).append(": ").append(notify.getProjectName()).append("\n"); } builder diff --git a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/group/PipelineGroupNotifyGenerator.java b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/group/PipelineGroupNotifyGenerator.java new file mode 100644 index 0000000..e166744 --- /dev/null +++ b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/service/notify/group/PipelineGroupNotifyGenerator.java @@ -0,0 +1,49 @@ +package dev.struchkov.bot.gitlab.telegram.service.notify.group; + +import dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline.PipelineGroupNotify; +import dev.struchkov.bot.gitlab.context.utils.Icons; +import dev.struchkov.bot.gitlab.telegram.service.notify.NotifyBoxAnswerGenerator; +import dev.struchkov.godfather.simple.domain.BoxAnswer; +import org.springframework.stereotype.Component; + +import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; +import static dev.struchkov.godfather.telegram.domain.keyboard.SimpleKeyBoardLine.keyBoardLine; +import static dev.struchkov.godfather.telegram.domain.keyboard.button.UrlButton.urlButton; +import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN; +import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; + +@Component +public class PipelineGroupNotifyGenerator implements NotifyBoxAnswerGenerator { + + @Override + public BoxAnswer generate(PipelineGroupNotify notify) { + final StringBuilder builder = new StringBuilder(Icons.BUILD).append(" ").append(notify.getOwnerTelegramUsername()).append(" *you started a new pipeline*") + .append(Icons.HR); + + if (checkNotEmpty(notify.getProjectName())) { + builder.append(Icons.PROJECT).append(": ").append(notify.getProjectName()).append("\n"); + } + + builder + .append(Icons.TREE).append(": ").append(notify.getRefName()) + .append(Icons.HR) + .append(notify.getOldStatus().getIcon()).append(" ").append(notify.getOldStatus()).append(Icons.ARROW).append(notify.getNewStatus().getIcon()).append(" ").append(notify.getNewStatus()); + + + return BoxAnswer.builder() + .message(builder.toString()) + .keyBoard(inlineKeyBoard( + keyBoardLine( + urlButton(Icons.LINK, notify.getWebUrl()) + ) + )) + .payload(ENABLE_MARKDOWN) + .build(); + } + + @Override + public String getNotifyType() { + return PipelineGroupNotify.TYPE; + } + +}