4 Commits

12 changed files with 339 additions and 41 deletions

View File

@@ -42,6 +42,11 @@
<artifactId>telegrambots</artifactId> <artifactId>telegrambots</artifactId>
<version>6.7.0</version> <version>6.7.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies> </dependencies>

View File

@@ -2,8 +2,11 @@ package ru.ldeloff.servermonitorbot;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import ru.ldeloff.servermonitorbot.config.SshConfig;
@SpringBootApplication @SpringBootApplication
@EnableConfigurationProperties(SshConfig.class)
public class ServerMonitorBotApplication { public class ServerMonitorBotApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@@ -0,0 +1,21 @@
package ru.ldeloff.servermonitorbot.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import ru.ldeloff.servermonitorbot.model.SshServer;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "ssh")
public class SshConfig {
private List<SshServer> servers;
public List<SshServer> getServers() {
return servers;
}
public void setServers(List<SshServer> servers) {
this.servers = servers;
}
}

View File

@@ -0,0 +1,20 @@
package ru.ldeloff.servermonitorbot.init;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import ru.ldeloff.servermonitorbot.service.SshService;
@Component
public class SshConnect implements ApplicationRunner {
final SshService sshService;
public SshConnect(SshService sshService) {
this.sshService = sshService;
}
@Override
public void run(ApplicationArguments args) throws Exception {
sshService.connectToAllServer();
}
}

View File

@@ -1,4 +1,4 @@
package ru.ldeloff.servermonitorbot; package ru.ldeloff.servermonitorbot.init;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -10,15 +10,16 @@ import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import ru.ldeloff.servermonitorbot.model.TelegramBot; import ru.ldeloff.servermonitorbot.model.TelegramBot;
import ru.ldeloff.servermonitorbot.service.TelegramBotService;
@Slf4j @Slf4j
@Component @Component
@NoArgsConstructor @NoArgsConstructor
public class StartBot implements ApplicationRunner { public class StartBot implements ApplicationRunner {
private TelegramBot telegramBot; private TelegramBotService telegramBot;
@Autowired @Autowired
public StartBot(TelegramBot telegramBot) { public StartBot(TelegramBotService telegramBot) {
this.telegramBot = telegramBot; this.telegramBot = telegramBot;
} }

View File

@@ -0,0 +1,24 @@
package ru.ldeloff.servermonitorbot.model;
import com.jcraft.jsch.Session;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
@Setter
@Getter
@Component
public class SshServer {
@NotNull
private String name;
@NotNull
private String host;
@NotNull
private int port;
@NotNull
private String user;
@NotNull
private String password;
private Session session;
}

View File

@@ -1,47 +1,17 @@
package ru.ldeloff.servermonitorbot.model; package ru.ldeloff.servermonitorbot.model;
import lombok.AllArgsConstructor; import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
@Getter
@Component @Component
@NoArgsConstructor public class TelegramBot{
@AllArgsConstructor private final String botUsername;
public class TelegramBot extends TelegramLongPollingBot { private final String botToken;
@Value("${bot.name}")
private String botUsername;
@Value("${bot.token}") public TelegramBot(@Value("${bot.name}") String botUsername, @Value("${bot.token}") String botToken) {
private String botToken; this.botUsername = botUsername;
this.botToken = botToken;
@Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
SendMessage message = new SendMessage(); // Create a SendMessage object with mandatory fields
message.setChatId(update.getMessage().getChatId().toString());
message.setText(update.getMessage().getText());
try {
execute(message); // Call method to send the message
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
@Override
public String getBotUsername() {
return botUsername;
}
@Override
public String getBotToken() {
return botToken;
} }
} }

View File

@@ -0,0 +1,16 @@
package ru.ldeloff.servermonitorbot.service;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import ru.ldeloff.servermonitorbot.model.SshServer;
import java.util.List;
public interface SshService {
void connectToAllServer();
Session connectToServer(SshServer sshServer) throws JSchException;
void disconnectSessions();
SendMessage getStatusSessions(Long chatId);
}

View File

@@ -0,0 +1,76 @@
package ru.ldeloff.servermonitorbot.service;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import ru.ldeloff.servermonitorbot.config.SshConfig;
import ru.ldeloff.servermonitorbot.model.SshServer;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class SshServiceImpl implements SshService{
private final List<SshServer> sshServers;
@Autowired
public SshServiceImpl(SshConfig sshConfig) {
this.sshServers = sshConfig.getServers();
}
private List<Session> sessions = new ArrayList<>();
@Override
public void connectToAllServer() {
sshServers.forEach(sshServer -> {
try {
Session session = connectToServer(sshServer);
sshServer.setSession(session);
log.info("Успешно подключён к " + sshServer.getHost());
sessions.add(session);
} catch (JSchException e) {
log.warn("Не удалось соединиться с " + sshServer.getHost() + ": " + e.getMessage());
}
});
}
@Override
public Session connectToServer(SshServer sshServer) throws JSchException {
Session session = new JSch().getSession(sshServer.getUser(),
sshServer.getHost(),
sshServer.getPort());
session.setPassword(sshServer.getPassword());
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
return session;
}
@Override
public void disconnectSessions() {
if (!sessions.isEmpty()) {
sessions.forEach(Session::disconnect);
sessions.forEach(sessions::remove);
}
}
@Override
public SendMessage getStatusSessions(Long chatId) {
StringBuilder text = new StringBuilder("Статус соединения: \n");
sshServers.forEach(server -> {
text.append(server.getName())
.append(": ")
.append(server.getSession().isConnected() ? "OK" : "отключён")
.append("\n");
});
SendMessage message = new SendMessage();
message.setText(String.valueOf(text));
message.setChatId(chatId);
return message;
}
}

View File

@@ -0,0 +1,92 @@
package ru.ldeloff.servermonitorbot.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import ru.ldeloff.servermonitorbot.model.TelegramBot;
import ru.ldeloff.servermonitorbot.util.TelegramBotMenu;
@Service
@Slf4j
public class TelegramBotService extends TelegramLongPollingBot {
final TelegramBot telegramBot;
final SshService sshService;
final TelegramBotMenu telegramBotMenu;
@Autowired
public TelegramBotService(TelegramBot telegramBot, SshService sshService, TelegramBotMenu telegramBotMenu) {
this.telegramBot = telegramBot;
this.sshService = sshService;
this.telegramBotMenu = telegramBotMenu;
}
@Override
public void onUpdateReceived(Update update) {
if (update.hasMessage()) {
if (update.getMessage().hasText()) {
SendMessage message = new SendMessage();
String messageText = update.getMessage().getText();
long chatId = update.getMessage().getChatId();
switch (messageText) {
case "/start":
message.setText("Привет: " + update.getMessage().getChat().getUserName());
message.setChatId(chatId);
message.setReplyMarkup(telegramBotMenu.initKeyboard());
sendMessage(message);
log.info("Получена команда /start");
break;
case "Статус":
sendMessage(sshService.getStatusSessions(chatId));
log.info("Получена команда 'Статус'");
break;
default:
message.setText("unknown command:" + messageText);
message.setChatId(chatId);
message.setReplyMarkup(telegramBotMenu.initKeyboard());
sendMessage(message);
log.warn("Неизвестная команда:" + messageText);
}
}
} else if (update.hasCallbackQuery()) {
try {
SendMessage message = new SendMessage();
message.setText(update.getCallbackQuery().getData());
message.setChatId(update.getCallbackQuery().getMessage().getChatId());
execute(message);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
private void sendMessage(SendMessage message) {
try {
execute(message);
} catch (TelegramApiException e) {
e.printStackTrace();
log.warn(e.getMessage());
}
}
@Override
public String getBotUsername() {
return telegramBot.getBotUsername();
}
@Override
public String getBotToken() {
return telegramBot.getBotToken();
}
@Override
public void onClosing() {
super.onClosing();
sshService.disconnectSessions();
}
}

View File

@@ -0,0 +1,61 @@
package ru.ldeloff.servermonitorbot.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardButton;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class TelegramBotMenu {
private final String STATUS = "Статус";
public ReplyKeyboardMarkup initKeyboard()
{
//Создаем объект будущей клавиатуры и выставляем нужные настройки
ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
replyKeyboardMarkup.setResizeKeyboard(true); //подгоняем размер
replyKeyboardMarkup.setOneTimeKeyboard(false); //скрываем после использования
//Создаем список с рядами кнопок
ArrayList<KeyboardRow> keyboardRows = new ArrayList<>();
//Создаем один ряд кнопок и добавляем его в список
KeyboardRow keyboardRow = new KeyboardRow();
keyboardRows.add(keyboardRow);
//Добавляем одну кнопку с текстом "Просвяти" наш ряд
keyboardRow.add(new KeyboardButton(STATUS));
//добавляем лист с одним рядом кнопок в главный объект
replyKeyboardMarkup.setKeyboard(keyboardRows);
return replyKeyboardMarkup;
}
public SendMessage mainMenu(long chatId) {
SendMessage message = new SendMessage();
message.setChatId(chatId);
message.setText("Choose an option:");
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
List<InlineKeyboardButton> keyboardRow = new ArrayList<>();
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton();
inlineKeyboardButton.setText(STATUS);
inlineKeyboardButton.setCallbackData("Button \"" + STATUS + "\" has been pressed");
keyboardRow.add(inlineKeyboardButton);
List<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
keyboard.add(keyboardRow);
inlineKeyboardMarkup.setKeyboard(keyboard);
message.setReplyMarkup(inlineKeyboardMarkup);
return message;
}
}

View File

@@ -1,5 +1,14 @@
bot: bot:
name: "ServerMonitorBot" name: "ServerMonitorBot"
token: "token" token: "token"
ssh:
servers:
-
name: "Server Name"
host: "url"
port: 22
user: "user"
password: "pass"