Skip to content

Commit 56816ee

Browse files
authored
Refactoring (#10)
* Refactoring * Fixed handling logic
1 parent fbfc7e6 commit 56816ee

16 files changed

+618
-310
lines changed

.idea/.gitignore

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.vality.alerting.tg.bot.handler.alert;
2+
3+
import dev.vality.alerting.tg.bot.model.Webhook;
4+
5+
import java.util.List;
6+
7+
public interface AlertHandler {
8+
boolean filter(String alertName);
9+
10+
void handle(Webhook webhook, List<Webhook.Alert> alerts);
11+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dev.vality.alerting.tg.bot.handler.alert;
2+
3+
import dev.vality.alerting.tg.bot.config.properties.AlertBotProperties;
4+
import dev.vality.alerting.tg.bot.model.Webhook;
5+
import dev.vality.alerting.tg.bot.service.FailedMachinesAlertService;
6+
import dev.vality.alerting.tg.bot.service.TelegramApiService;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Component;
10+
11+
import java.util.ArrayList;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
import static dev.vality.alerting.tg.bot.constant.AlertThreadName.FAILED_MACHINES;
17+
import static dev.vality.alerting.tg.bot.util.WebhookUtil.formatWebhook;
18+
19+
@Slf4j
20+
@Component
21+
@RequiredArgsConstructor
22+
public class FailedMachinesAlertHandler implements AlertHandler {
23+
private final AlertBotProperties properties;
24+
private final TelegramApiService telegramApiService;
25+
private final FailedMachinesAlertService service;
26+
27+
@Override
28+
public boolean filter(String alertName) {
29+
return FAILED_MACHINES.equals(alertName);
30+
}
31+
32+
@Override
33+
public void handle(Webhook webhook, List<Webhook.Alert> alerts) {
34+
Map<Integer, List<Webhook.Alert>> threadIds = new HashMap<>();
35+
36+
for (Webhook.Alert alert : alerts) {
37+
Integer threadId = service.getOrCreateTopicIdForFailedMachinesAlert(alert);
38+
threadIds.computeIfAbsent(threadId, key -> new ArrayList<>()).add(alert);
39+
}
40+
41+
threadIds.forEach((threadId, threadAlerts) -> {
42+
telegramApiService.sendMessage(
43+
properties.getChatId(),
44+
threadId,
45+
formatWebhook(webhook),
46+
"MarkdownV2"
47+
);
48+
});
49+
}
50+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package dev.vality.alerting.tg.bot.handler.alert;
2+
3+
import dev.vality.alerting.tg.bot.config.properties.AlertBotProperties;
4+
import dev.vality.alerting.tg.bot.model.Webhook;
5+
import dev.vality.alerting.tg.bot.service.TelegramApiService;
6+
import jakarta.annotation.PostConstruct;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Component;
10+
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
import static dev.vality.alerting.tg.bot.constant.AlertThreadName.*;
15+
import static dev.vality.alerting.tg.bot.constant.AlertThreadName.PENDING_PAYMENTS;
16+
import static dev.vality.alerting.tg.bot.util.WebhookUtil.formatWebhook;
17+
18+
@Slf4j
19+
@Component
20+
@RequiredArgsConstructor
21+
public class UnknownAlertHandler implements AlertHandler {
22+
private final AlertBotProperties properties;
23+
private final TelegramApiService telegramApiService;
24+
private Map<String, Integer> alertThreads;
25+
26+
@PostConstruct
27+
public void init() {
28+
alertThreads = buildAlertThreadMap();
29+
}
30+
31+
@Override
32+
public boolean filter(String alertName) {
33+
return false;
34+
}
35+
36+
@Override
37+
public void handle(Webhook webhook, List<Webhook.Alert> alerts) {
38+
if (alerts == null || alerts.isEmpty()) {
39+
return;
40+
}
41+
42+
String alertName = alerts.get(0).getLabels() != null ? alerts.get(0).getLabels().getAlertname() : null;
43+
44+
Integer threadId = alertThreads.get(alertName);
45+
if (threadId == null) {
46+
log.error("Неизвестный тип алерта, alertName=" + alertName);
47+
threadId = properties.getThreads().getCommands();
48+
}
49+
50+
telegramApiService.sendMessage(
51+
properties.getChatId(),
52+
threadId,
53+
formatWebhook(webhook),
54+
"MarkdownV2"
55+
);
56+
}
57+
58+
private Map<String, Integer> buildAlertThreadMap() {
59+
return Map.of(
60+
API_ERROR_HTTP_CODE_INCREASE, properties.getThreads().getErrors5xx(),
61+
ALT_PAY_CONVERSION, properties.getThreads().getAltpayConversion(),
62+
FAILED_MACHINES, properties.getThreads().getFailedMachines(),
63+
PENDING_PAYMENTS, properties.getThreads().getPendingPayments()
64+
);
65+
}
66+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package dev.vality.alerting.tg.bot.handler.command;
2+
3+
import dev.vality.alerting.tg.bot.config.properties.AlertBotProperties;
4+
import dev.vality.alerting.tg.bot.service.CommandStateService;
5+
import dev.vality.alerting.tg.bot.service.TelegramApiService;
6+
import lombok.RequiredArgsConstructor;
7+
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.core.annotation.Order;
9+
import org.springframework.stereotype.Component;
10+
import org.telegram.telegrambots.meta.api.objects.Update;
11+
12+
@Slf4j
13+
@Component
14+
@RequiredArgsConstructor
15+
@Order(20)
16+
public class CreateAlertThreadCommandHandler implements TelegramCommandHandler {
17+
18+
private static final String COMMAND = "/create_alert_topic";
19+
20+
private final AlertBotProperties properties;
21+
private final CommandStateService commandStateService;
22+
private final TelegramApiService telegramApiService;
23+
24+
@Override
25+
public boolean filter(Update update) {
26+
var message = update.getMessage();
27+
28+
Integer threadId = message.getMessageThreadId();
29+
if (threadId == null || !threadId.equals(properties.getThreads().getCommands())) {
30+
return false;
31+
}
32+
33+
String text = message.getText();
34+
if (text == null) {
35+
return false;
36+
}
37+
38+
return text.trim().startsWith(COMMAND);
39+
}
40+
41+
@Override
42+
public void handle(Update update) {
43+
var message = update.getMessage();
44+
Long chatId = message.getChatId();
45+
46+
commandStateService.markWaitingForNewThreadName(chatId);
47+
48+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(),
49+
"Введите название для нового треда:", null);
50+
51+
log.info("Create alert thread command accepted. chatId={}, user=@{}",
52+
chatId,
53+
message.getFrom() != null ? message.getFrom().getUserName() : null
54+
);
55+
}
56+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package dev.vality.alerting.tg.bot.handler.command;
2+
3+
import dev.vality.alerting.tg.bot.config.properties.AlertBotProperties;
4+
import dev.vality.alerting.tg.bot.exception.TelegramThreadCreationException;
5+
import dev.vality.alerting.tg.bot.service.CommandStateService;
6+
import dev.vality.alerting.tg.bot.service.TelegramApiService;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.core.annotation.Order;
10+
import org.springframework.stereotype.Component;
11+
import org.telegram.telegrambots.meta.api.methods.forum.CreateForumTopic;
12+
import org.telegram.telegrambots.meta.api.objects.Update;
13+
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
14+
import org.telegram.telegrambots.meta.generics.TelegramClient;
15+
16+
@Slf4j
17+
@Component
18+
@RequiredArgsConstructor
19+
@Order(10)
20+
public class EnterAlertThreadNameHandler implements TelegramCommandHandler {
21+
private final AlertBotProperties properties;
22+
private final CommandStateService commandStateService;
23+
private final TelegramApiService telegramApiService;
24+
private final TelegramClient telegramClient;
25+
26+
@Override
27+
public boolean filter(Update update) {
28+
var message = update.getMessage();
29+
30+
Integer threadId = message.getMessageThreadId();
31+
if (threadId == null || !threadId.equals(properties.getThreads().getCommands())) {
32+
return false;
33+
}
34+
35+
Long chatId = message.getChatId();
36+
if (chatId == null) {
37+
return false;
38+
}
39+
40+
return commandStateService.isWaitingForNewThreadName(chatId);
41+
}
42+
43+
@Override
44+
public void handle(Update update) {
45+
var message = update.getMessage();
46+
Long chatId = message.getChatId();
47+
48+
commandStateService.clearWaitingForNewThreadName(chatId);
49+
50+
String threadName = message.getText() != null ? message.getText().trim() : "";
51+
if (threadName.isBlank()) {
52+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(),
53+
"Название треда не может быть пустым. Повторите /create_alert_topic.", null);
54+
return;
55+
}
56+
57+
if (threadName.startsWith("/")) {
58+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(),
59+
"Ожидалось название треда (обычный текст), а не команда. Повторите /create_alert_topic.", null);
60+
return;
61+
}
62+
63+
try {
64+
CreateForumTopic createForumTopic = CreateForumTopic.builder()
65+
.chatId(chatId.toString())
66+
.name(threadName)
67+
.build();
68+
69+
Integer messageThreadId = telegramClient.execute(createForumTopic).getMessageThreadId();
70+
if (messageThreadId == null) {
71+
throw new TelegramThreadCreationException("Telegram вернул null messageThreadId: threadName='" +
72+
threadName + "'");
73+
}
74+
75+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(),
76+
"✅ Тред '" + threadName + "' создан.", null);
77+
} catch (TelegramApiException e) {
78+
log.error("Ошибка при создании треда", e);
79+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(),
80+
"❌ Ошибка при создании треда.", null);
81+
}
82+
}
83+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dev.vality.alerting.tg.bot.handler.command;
2+
3+
import org.telegram.telegrambots.meta.api.objects.Update;
4+
5+
public interface TelegramCommandHandler {
6+
7+
boolean filter(final Update update);
8+
9+
void handle(Update update);
10+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package dev.vality.alerting.tg.bot.handler.command;
2+
3+
import dev.vality.alerting.tg.bot.config.properties.AlertBotProperties;
4+
import dev.vality.alerting.tg.bot.service.TelegramApiService;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.slf4j.Slf4j;
7+
import org.springframework.core.annotation.Order;
8+
import org.springframework.stereotype.Component;
9+
import org.telegram.telegrambots.meta.api.objects.Update;
10+
11+
@Slf4j
12+
@Component
13+
@RequiredArgsConstructor
14+
@Order(1000)
15+
public class UnknownCommandHandler implements TelegramCommandHandler {
16+
private final AlertBotProperties properties;
17+
private final TelegramApiService telegramApiService;
18+
19+
20+
@Override
21+
public boolean filter(Update update) {
22+
var message = update.getMessage();
23+
Integer threadId = message.getMessageThreadId();
24+
if (threadId == null || !threadId.equals(properties.getThreads().getCommands())) {
25+
return false;
26+
}
27+
28+
String text = message.getText();
29+
return text != null && text.trim().startsWith("/");
30+
}
31+
32+
@Override
33+
public void handle(Update update) {
34+
var message = update.getMessage();
35+
Long chatId = message.getChatId();
36+
37+
telegramApiService.sendMessage(chatId, properties.getThreads().getCommands(), "Неизвестная команда.", null);
38+
log.info("Введена неизвестная команда message:" + message);
39+
}
40+
}

0 commit comments

Comments
 (0)