Рефакторинг

This commit is contained in:
Struchkov Mark 2024-01-27 09:39:06 +03:00
parent 67e14ca2b5
commit 8f48af4767
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
17 changed files with 153 additions and 125 deletions

View File

@ -4,8 +4,7 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import static dev.struchkov.haiti.utils.Checker.checkNotNull; import java.util.Optional;
import static dev.struchkov.haiti.utils.Checker.checkNull;
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
@ -18,18 +17,18 @@ public enum AssigneeChanged {
private final boolean changed; private final boolean changed;
public static AssigneeChanged valueOf(Long gitlabUserId, Person oldAssignee, Person newAssignee) { public static AssigneeChanged valueOf(Long gitlabUserId, Optional<Person> oldAssignee, Optional<Person> newAssignee) {
if (checkNull(oldAssignee) && checkNotNull(newAssignee) && gitlabUserId.equals(newAssignee.getId())) { if (oldAssignee.isEmpty() && newAssignee.isPresent() && gitlabUserId.equals(newAssignee.get().getId())) {
return AssigneeChanged.BECOME; return AssigneeChanged.BECOME;
} }
if (checkNotNull(oldAssignee) && checkNull(newAssignee) && gitlabUserId.equals(oldAssignee.getId())) { if (oldAssignee.isPresent() && newAssignee.isEmpty() && gitlabUserId.equals(oldAssignee.get().getId())) {
return AssigneeChanged.DELETED; return AssigneeChanged.DELETED;
} }
if (checkNotNull(oldAssignee) && checkNotNull(newAssignee) && !oldAssignee.getId().equals(newAssignee.getId())) { if (oldAssignee.isPresent() && newAssignee.isPresent() && !oldAssignee.get().getId().equals(newAssignee.get().getId())) {
if (gitlabUserId.equals(oldAssignee.getId())) { if (gitlabUserId.equals(oldAssignee.get().getId())) {
return AssigneeChanged.DELETED; return AssigneeChanged.DELETED;
} }
if (gitlabUserId.equals(newAssignee.getId())) { if (gitlabUserId.equals(newAssignee.get().getId())) {
return AssigneeChanged.BECOME; return AssigneeChanged.BECOME;
} }
return AssigneeChanged.NOT_AFFECT_USER; return AssigneeChanged.NOT_AFFECT_USER;

View File

@ -81,10 +81,11 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) { private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
final Long gitlabUserId = personInformation.getId(); final Long gitlabUserId = personInformation.getId();
final Person assignee = mergeRequest.getAssignee(); final Optional<Person> optAssignee = getAssignee(mergeRequest);
final Person author = mergeRequest.getAuthor(); final Person author = mergeRequest.getAuthor();
if (checkNotNull(assignee)) { if (optAssignee.isPresent()) {
final Person assignee = optAssignee.get();
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) { if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
return true; return true;
} }
@ -116,8 +117,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
} }
private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) { private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) {
notifyService.send( final NewMrForReview.NewMrForReviewBuilder builder = NewMrForReview.builder()
NewMrForReview.builder()
.mrId(mergeRequest.getId()) .mrId(mergeRequest.getId())
.projectName(projectName) .projectName(projectName)
.labels(mergeRequest.getLabels()) .labels(mergeRequest.getLabels())
@ -126,10 +126,17 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.title(mergeRequest.getTitle()) .title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl()) .url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch()) .targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch()) .sourceBranch(mergeRequest.getSourceBranch());
.assignee(mergeRequest.getAssignee().getName())
.build() getAssignee(mergeRequest)
); .map(Person::getName)
.ifPresent(builder::assignee);
notifyService.send(builder.build());
}
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
return Optional.ofNullable(mergeRequest.getAssignee());
} }
private void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) { private void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) {
@ -148,9 +155,9 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
if (checkNotNull(oldAssigneeName)) { if (checkNotNull(oldAssigneeName)) {
builder.oldAssigneeName(oldAssigneeName); builder.oldAssigneeName(oldAssigneeName);
if (checkNotNull(mergeRequest.getAssignee())) { getAssignee(mergeRequest)
builder.newAssigneeName(mergeRequest.getAssignee().getName()); .map(Person::getName)
} .ifPresent(builder::newAssigneeName);
} }
notifyService.send(builder.build()); notifyService.send(builder.build());
@ -165,7 +172,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
mergeRequest.setNotification(oldMergeRequest.isNotification()); mergeRequest.setNotification(oldMergeRequest.isNotification());
final Long gitlabUserId = personInformation.getId(); final Long gitlabUserId = personInformation.getId();
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, oldMergeRequest.getAssignee(), mergeRequest.getAssignee()); final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, getAssignee(oldMergeRequest), getAssignee(mergeRequest));
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers()); final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee())); mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee()));
@ -201,8 +208,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
switch (assigneeChanged) { switch (assigneeChanged) {
case BECOME -> case BECOME -> sendNotifyNewAssignee(mergeRequest, project.getName(), getAssignee(oldMergeRequest).map(Person::getName).orElse(null));
sendNotifyNewAssignee(mergeRequest, project.getName(), Optional.ofNullable(oldMergeRequest.getAssignee()).map(Person::getName).orElse(null));
} }
} }
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера //TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера

View File

@ -102,7 +102,8 @@ public class PipelineServiceImpl implements PipelineService {
final Person personPipelineCreator = pipeline.getPerson(); final Person personPipelineCreator = pipeline.getPerson();
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null && checkNotNull(personPipelineCreator) // Создатель пайплайна не null
&& personInformation.getId().equals(personPipelineCreator.getId()); // Пользователь приложения является инициатором пайплайна && personInformation.getId().equals(personPipelineCreator.getId()) // Пользователь приложения является инициатором пайплайна
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
} }
@Override @Override
@ -128,7 +129,7 @@ public class PipelineServiceImpl implements PipelineService {
@Override @Override
public void cleanOld() { public void cleanOld() {
log.debug("Старт очистки старых пайплайнов"); log.debug("Старт очистки старых пайплайнов");
repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(1L)); repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(7L));
log.debug("Конец очистки старых пайплайнов"); log.debug("Конец очистки старых пайплайнов");
} }

View File

@ -35,6 +35,7 @@ import static dev.struchkov.haiti.utils.Checker.checkFalse;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult; import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults; import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
import static java.util.stream.Collectors.toMap;
/** /**
* Парсер пайплайнов. * Парсер пайплайнов.
@ -79,7 +80,7 @@ public class PipelineParser {
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable(); final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream() final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
.collect(Collectors.toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId)); .collect(toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
if (checkNotEmpty(pipelineProjectMap)) { if (checkNotEmpty(pipelineProjectMap)) {
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet()); final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet());
@ -99,14 +100,16 @@ public class PipelineParser {
log.debug("Конец обработки новых пайплайнов"); log.debug("Конец обработки новых пайплайнов");
} }
private List<Pipeline> getNewPipelines(Map<Long, Long> pipelineProjectMap, Set<Long> idsNotFound) { private List<Pipeline> getNewPipelines(Map<Long, Long> pipelineIdAndProjectId, Set<Long> idsNotFound) {
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = idsNotFound.stream() final List<ForkJoinTask<Optional<PipelineJson>>> tasks = idsNotFound.stream()
.map(pipelineId -> new GetPipelineTask( .map(
gitlabProperty.getPipelineUrl(), pipelineId -> GetPipelineTask.builder()
pipelineProjectMap.get(pipelineId), .pipelineId(pipelineId)
pipelineId, .projectId(pipelineIdAndProjectId.get(pipelineId))
personProperty.getToken() .urlPipeline(gitlabProperty.getPipelineUrl())
)) .gitlabToken(personProperty.getToken())
.build()
)
.map(forkJoinPool::submit) .map(forkJoinPool::submit)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -141,12 +144,13 @@ public class PipelineParser {
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = pipelines.stream() final List<ForkJoinTask<Optional<PipelineJson>>> tasks = pipelines.stream()
.map( .map(
pipeline -> new GetPipelineTask( pipeline ->
gitlabProperty.getPipelineUrl(), GetPipelineTask.builder()
pipeline.getProjectId(), .projectId(pipeline.getProjectId())
pipeline.getId(), .pipelineId(pipeline.getId())
personProperty.getToken() .urlPipeline(gitlabProperty.getPipelineUrl())
) .gitlabToken(gitlabProperty.getPipelineUrl())
.build()
) )
.map(forkJoinPool::submit) .map(forkJoinPool::submit)
.collect(Collectors.toList()); .collect(Collectors.toList());

View File

@ -3,7 +3,10 @@ package dev.struchkov.bot.gitlab.core.service.parser.forktask;
import dev.struchkov.bot.gitlab.core.utils.HttpParse; import dev.struchkov.bot.gitlab.core.utils.HttpParse;
import dev.struchkov.bot.gitlab.core.utils.StringUtils; import dev.struchkov.bot.gitlab.core.utils.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson; import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
import lombok.RequiredArgsConstructor; import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -15,13 +18,15 @@ import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
@Slf4j @Slf4j
@RequiredArgsConstructor @Builder
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class GetPipelineTask extends RecursiveTask<Optional<PipelineJson>> { public class GetPipelineTask extends RecursiveTask<Optional<PipelineJson>> {
private final String urlPipeline; private String urlPipeline;
private final long projectId; private long projectId;
private final long pipelineId; private long pipelineId;
private final String gitlabToken; private String gitlabToken;
@Override @Override
@SneakyThrows @SneakyThrows

View File

@ -19,7 +19,8 @@ spring:
logging: logging:
level: level:
"dev.struchkov": ${LOG_LEVEL:info} "dev.struchkov": ${LOG_LEVEL:INFO}
"dev.struchkov.bot.gitlab": ${APP_LOG_LEVEL:INFO}
telegram: telegram:
bot: bot:
@ -39,9 +40,9 @@ gitlab-bot:
version: 1.0.0 version: 1.0.0
cron: cron:
scan: scan:
general: "0 */1 * * * *" general: ${CRON_GENERAL:0 */1 * * * *}
new-project: "0 0 */1 * * *" new-project: ${CRON_NEW_PROJECTS:0 0 */1 * * *}
new-merge-request: "0 */15 * * * *" new-merge-request: ${CRON_NEW_MR:0 */15 * * * *}
person: person:
telegram-id: ${TELEGRAM_PERSON_ID} telegram-id: ${TELEGRAM_PERSON_ID}
token: ${GITLAB_PERSONAL_TOKEN} token: ${GITLAB_PERSONAL_TOKEN}

View File

@ -9,11 +9,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component @Component
@ -30,16 +30,18 @@ public class ConflictPrNotifyGenerator implements NotifyBoxAnswerGenerator<Confl
.append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())); .append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch()));
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage, return BoxAnswer.builder()
inlineKeyBoard( .message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -9,11 +9,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component @Component
@ -30,16 +30,18 @@ public class ConflictResolvePrNotifyGenerator implements NotifyBoxAnswerGenerato
.append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())); .append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch()));
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage, return BoxAnswer.builder()
inlineKeyBoard( .message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -10,10 +10,10 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank; import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -51,14 +51,16 @@ public class NewCommentNotifyGenerator implements NotifyBoxAnswerGenerator<NewCo
} }
final String messageNotify = builder.toString(); final String messageNotify = builder.toString();
return boxAnswer(
messageNotify, return BoxAnswer.builder()
inlineKeyBoard( .message(messageNotify)
.keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -11,11 +11,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -52,16 +52,18 @@ public class NewMrForReviewNotifyGenerator implements NotifyBoxAnswerGenerator<N
} }
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage, return BoxAnswer.builder()
inlineKeyBoard( .message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -11,11 +11,11 @@ import org.springframework.stereotype.Component;
import java.util.Optional; import java.util.Optional;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component @Component
@ -46,16 +46,17 @@ public class NewProjectNotifyGenerator implements NotifyBoxAnswerGenerator<NewPr
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer( return BoxAnswer.builder()
notifyMessage, .message(notifyMessage)
inlineKeyBoard( .keyBoard(inlineKeyBoard(
keyBoardLine(urlButton(Icons.LINK, notify.getProjectUrl())), keyBoardLine(urlButton(Icons.LINK, notify.getProjectUrl())),
keyBoardLine( keyBoardLine(
simpleButton(Icons.NOTIFY, "[" + Const.BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID + ":" + notify.getProjectId() + "]"), simpleButton(Icons.NOTIFY, "[" + Const.BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID + ":" + notify.getProjectId() + "]"),
simpleButton(Icons.DISABLE_NOTIFY, DELETE_MESSAGE) simpleButton(Icons.DISABLE_NOTIFY, DELETE_MESSAGE)
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -13,10 +13,10 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank; import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -49,14 +49,16 @@ public class NewThreadNotifyGenerator implements NotifyBoxAnswerGenerator<Discus
} }
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage, return BoxAnswer.builder()
inlineKeyBoard( .message(notifyMessage)
.keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
private String convertNotes(List<Pair<String, String>> notes) { private String convertNotes(List<Pair<String, String>> notes) {

View File

@ -11,11 +11,11 @@ import org.springframework.stereotype.Service;
import java.util.Optional; import java.util.Optional;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@ -42,15 +42,16 @@ public class PipelineNotifyGenerator implements NotifyBoxAnswerGenerator<Pipelin
builder builder
.append(Icons.TREE).append(": ").append(notify.getRefName()); .append(Icons.TREE).append(": ").append(notify.getRefName());
return boxAnswer( return BoxAnswer.builder()
builder.toString(), .message(builder.toString())
inlineKeyBoard( .keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getWebUrl()) urlButton(Icons.LINK, notify.getWebUrl())
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -6,11 +6,11 @@ import dev.struchkov.godfather.simple.domain.BoxAnswer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component @Component
@ -28,15 +28,16 @@ public class StatusMrNotifyGenerator implements NotifyBoxAnswerGenerator<StatusM
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer( return BoxAnswer.builder()
notifyMessage, .message(notifyMessage)
inlineKeyBoard( .keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()) urlButton(Icons.LINK, notify.getUrl())
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -6,10 +6,10 @@ import dev.struchkov.godfather.simple.domain.BoxAnswer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank; import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -38,13 +38,14 @@ public class ThreadCloseNotifyGenerate implements NotifyBoxAnswerGenerator<Threa
} }
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer( return BoxAnswer.builder()
notifyMessage, .message(notifyMessage)
inlineKeyBoard( .keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()) urlButton(Icons.LINK, notify.getUrl())
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -9,11 +9,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID;
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE; import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard; 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.SimpleKeyBoardLine.keyBoardLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton; 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.domain.keyboard.button.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank; import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown; import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -52,16 +52,17 @@ public class UpdateMrNotifyGenerator implements NotifyBoxAnswerGenerator<UpdateM
.append(Icons.AUTHOR).append(": ").append(notify.getAuthor()); .append(Icons.AUTHOR).append(": ").append(notify.getAuthor());
final String notifyMessage = builder.toString(); final String notifyMessage = builder.toString();
return boxAnswer( return BoxAnswer.builder()
notifyMessage, .message(notifyMessage)
inlineKeyBoard( .keyBoard(inlineKeyBoard(
keyBoardLine( keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE), simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()), urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]") simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
) )
) ))
); .payload(ENABLE_MARKDOWN)
.build();
} }
@Override @Override

View File

@ -11,17 +11,16 @@ import dev.struchkov.godfather.simple.domain.unit.AnswerText;
import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment; import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment;
import dev.struchkov.godfather.telegram.main.core.util.Attachments; import dev.struchkov.godfather.telegram.main.core.util.Attachments;
import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration; import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration;
import dev.struchkov.haiti.utils.Checker;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.ANSWER_NOTE; import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.ANSWER_NOTE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer; import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@ -40,11 +39,9 @@ public class AnswerNoteUnit implements PersonUnitConfiguration {
return AnswerText.<Mail>builder() return AnswerText.<Mail>builder()
.triggerCheck( .triggerCheck(
mail -> { mail -> {
final List<Mail> forwardMails = mail.getForwardMail(); final Mail replay = mail.getReplayMail();
if (Checker.checkNotNull(forwardMails) && forwardMails.size() == 1) { if (checkNotNull(replay)) {
final Mail forwardMail = forwardMails.get(0); final boolean isLink = Attachments.findFirstLink(replay.getAttachments()).isPresent();
final boolean isLink = Attachments.findFirstLink(forwardMail.getAttachments())
.isPresent();
if (isLink) { if (isLink) {
final boolean isAccess = personInformation.getTelegramId().equals(mail.getFromPersonId()); final boolean isAccess = personInformation.getTelegramId().equals(mail.getFromPersonId());
final boolean firstStart = settingService.isFirstStart(); final boolean firstStart = settingService.isFirstStart();
@ -56,7 +53,7 @@ public class AnswerNoteUnit implements PersonUnitConfiguration {
) )
.answer( .answer(
mail -> { mail -> {
final String noteUrl = Attachments.findFirstLink(mail.getForwardMail().get(0).getAttachments()) final String noteUrl = Attachments.findFirstLink(mail.getReplayMail().getAttachments())
.map(LinkAttachment::getUrl) .map(LinkAttachment::getUrl)
.orElseThrow(); .orElseThrow();
final Matcher matcher = NOTE_LINK.matcher(noteUrl); final Matcher matcher = NOTE_LINK.matcher(noteUrl);