diff --git a/src/main/java/ru/cathub/telegabot/bot/KeyboardHelper.java b/src/main/java/ru/cathub/telegabot/bot/KeyboardHelper.java index d57079c..f0047b3 100644 --- a/src/main/java/ru/cathub/telegabot/bot/KeyboardHelper.java +++ b/src/main/java/ru/cathub/telegabot/bot/KeyboardHelper.java @@ -66,22 +66,21 @@ public class KeyboardHelper { } public static ReplyKeyboardMarkup getBookMenuKeyboard() { - List keyboardRows = new ArrayList<>(); KeyboardRow row1 = new KeyboardRow(); row1.add(new KeyboardButton(ADD_BOOK)); - row1.add(new KeyboardButton(LIST_BOOKS)); + row1.add(new KeyboardButton(EDIT_BOOKS)); KeyboardRow row2 = new KeyboardRow(); - row2.add(new KeyboardButton(EDIT_BOOKS)); + row2.add(new KeyboardButton(LIST_BOOKS)); + row2.add(new KeyboardButton(FILTER_BOOKS)); KeyboardRow row3 = new KeyboardRow(); + row3.add(new KeyboardButton(RECOMMEND_BOOKS)); row3.add(new KeyboardButton(SET_BOOKS_GOAL_FROM_BOOKS)); row3.add(new KeyboardButton(BACK)); - keyboardRows.add(row1); - keyboardRows.add(row2); - keyboardRows.add(row3); + List keyboardRows = List.of(row1,row2,row3); ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup(keyboardRows); keyboardMarkup.setResizeKeyboard(true); @@ -202,4 +201,33 @@ public class KeyboardHelper { } + public static ReplyKeyboardMarkup getAiMenuKeyboard(BotUser.WorkingMode workingMode) { + + + KeyboardRow row1 = new KeyboardRow(); + KeyboardRow row2 = new KeyboardRow(); + + switch (workingMode) { + case AI_FILTER -> { + row1.add(new KeyboardButton(AI_FILTER_GENRE)); + row2.add(new KeyboardButton(AI_FILTER_RATING)); + } + case AI_SUGGEST -> { + row1.add(new KeyboardButton(AI_SUGGEST_GENRE)); + row2.add(new KeyboardButton(AI_SUGGEST_SIMILAR)); + } + } + + KeyboardRow row3 = new KeyboardRow(); + row3.add(new KeyboardButton(BACK)); + + List keyboardRows = List.of(row1,row2,row3); + + ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup(keyboardRows); + keyboardMarkup.setResizeKeyboard(true); + keyboardMarkup.setOneTimeKeyboard(false); + + return keyboardMarkup; + + } } diff --git a/src/main/java/ru/cathub/telegabot/model/BotUser.java b/src/main/java/ru/cathub/telegabot/model/BotUser.java index 0d03d79..2bddb4f 100644 --- a/src/main/java/ru/cathub/telegabot/model/BotUser.java +++ b/src/main/java/ru/cathub/telegabot/model/BotUser.java @@ -21,7 +21,7 @@ public class BotUser { USER, ADMIN } public enum WorkingMode { - BOOK,TORRENT,AI,EDIT_PROFILE,NO_MODE + BOOK,TORRENT,AI,EDIT_PROFILE,NO_MODE,AI_FILTER,AI_SUGGEST } private Integer booksToRead; diff --git a/src/main/java/ru/cathub/telegabot/model/TextRole.java b/src/main/java/ru/cathub/telegabot/model/TextRole.java index a968330..17b12a5 100644 --- a/src/main/java/ru/cathub/telegabot/model/TextRole.java +++ b/src/main/java/ru/cathub/telegabot/model/TextRole.java @@ -3,7 +3,12 @@ package ru.cathub.telegabot.model; public enum TextRole { DEFAULT("Ты книжный ассистент в Telegram-боте. Отвечай, используй эмоджи, разметку Markdown (*для\n" + " выделения*, _для наклонного_). Отвечай ТОЛЬКО на русском языке."), - REVIEWER("Анализируй текст как профессиональный редактор"), + SUGGESTER("Ты книжный ассистент в Telegram-боте, который помогает находить новые книги. Отвечай, используй эмоджи, разметку Markdown (*для\n" + + " выделения*, _для наклонного_). Тебе будет передан список книг пользователя и ты должен проанализировать\n" + + " этот список, и далее отвечать операясь на предпочтения пользоватья из этого списка"), + FILTERER("Ты книжный ассистент в Telegram-боте, который фильтрует списки. Отвечай, используй эмоджи, разметку Markdown (*для\n" + + " выделения*, _для наклонного_). Тебе будет передан список книг пользователя и ты должен вывести книги,\n"+ + " которые удовлетворяют запросу пользователя из этого списка. Если таких книг нет, то отвечай, что книги не найдены"), RECOMMENDER("Рекомендуй книги на основе предпочтений"); private final String systemPrompt; diff --git a/src/main/java/ru/cathub/telegabot/service/BookAiService.java b/src/main/java/ru/cathub/telegabot/service/BookAiService.java new file mode 100644 index 0000000..ac7d0a7 --- /dev/null +++ b/src/main/java/ru/cathub/telegabot/service/BookAiService.java @@ -0,0 +1,9 @@ +package ru.cathub.telegabot.service; + +import ru.cathub.telegabot.model.BotUser; + +public interface BookAiService { + void processAiRequest(BotUser user, String text, BotUser.WorkingMode workingMode); + + void handleAiStartMessage(BotUser botUser, BotUser.WorkingMode workingMode); +} diff --git a/src/main/java/ru/cathub/telegabot/service/impl/BookAiServiceImpl.java b/src/main/java/ru/cathub/telegabot/service/impl/BookAiServiceImpl.java new file mode 100644 index 0000000..7d6999e --- /dev/null +++ b/src/main/java/ru/cathub/telegabot/service/impl/BookAiServiceImpl.java @@ -0,0 +1,58 @@ +package ru.cathub.telegabot.service.impl; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.cathub.telegabot.bot.KeyboardHelper; +import ru.cathub.telegabot.model.BotUser; +import ru.cathub.telegabot.model.TextRole; +import ru.cathub.telegabot.repository.UserRepository; +import ru.cathub.telegabot.service.BookAiService; +import ru.cathub.telegabot.service.TelegramClientService; + +import static ru.cathub.telegabot.model.BotUser.WorkingMode.*; +import static ru.cathub.telegabot.utils.BookFormatUtils.escapeNonMarkdown; + +@Service +@RequiredArgsConstructor +@Slf4j +public class BookAiServiceImpl implements BookAiService { + + private final UserRepository userRepository; + private final TelegramClientService telegramClientService; + private final OpenRouterServiceImpl openRouterServiceImpl; + + @Override + public void processAiRequest(BotUser user, String text, BotUser.WorkingMode workingMode) { + try { + String response = null; + switch (workingMode) { + case AI_FILTER -> {response = openRouterServiceImpl.getChatResponse(text, TextRole.FILTERER);} + case AI_SUGGEST -> {response =openRouterServiceImpl.getChatResponse(text, TextRole.SUGGESTER);} + } + telegramClientService.sendMessageWithMarkdown(user, escapeNonMarkdown(response)); + } + catch (Exception e) { + log.error("Error processing AI request for user {}", user.getId(), e); + telegramClientService.sendMessage(user, "x Ошибка в ответе от AI"); + } + } + + @Override + public void handleAiStartMessage(BotUser botUser, BotUser.WorkingMode workingMode) { + botUser.setWorkingMode(workingMode); + userRepository.save(botUser); + telegramClientService.sendMessageWithMarkdown(botUser + , getWelcomeMessage(workingMode) + , KeyboardHelper.getAiMenuKeyboard(workingMode)); + } + + private String getWelcomeMessage(BotUser.WorkingMode workingMode) { + if (workingMode == AI_FILTER) { + return "Введите запрос к AI для фильтрации книг или выберите один из примеров запроса"; + } else if (workingMode == AI_SUGGEST) { + return "Введите запрос к AI для предложения книг или выберите один из примеров запроса"; + } + return "Введите запрос к AI"; + } +} diff --git a/src/main/java/ru/cathub/telegabot/service/impl/BookManageServiceImpl.java b/src/main/java/ru/cathub/telegabot/service/impl/BookManageServiceImpl.java index 20d2a7e..e627574 100644 --- a/src/main/java/ru/cathub/telegabot/service/impl/BookManageServiceImpl.java +++ b/src/main/java/ru/cathub/telegabot/service/impl/BookManageServiceImpl.java @@ -11,6 +11,8 @@ import ru.cathub.telegabot.repository.BookRepository; import ru.cathub.telegabot.repository.UserRepository; import ru.cathub.telegabot.service.*; +import static ru.cathub.telegabot.model.BotUser.WorkingMode.AI_FILTER; +import static ru.cathub.telegabot.model.BotUser.WorkingMode.AI_SUGGEST; import static ru.cathub.telegabot.utils.Constants.*; @@ -26,6 +28,7 @@ public class BookManageServiceImpl implements BookManageService { private final BookCacheService bookCacheService; private final BookRepository bookRepository; private final TelegramClientService telegramClientService; + private final BookAiService bookAiService; @@ -52,6 +55,12 @@ public class BookManageServiceImpl implements BookManageService { bookCacheService.clearBookEditCache(userId); bookCreationService.handleNewAddRequest(user, text); break; + case RECOMMEND_BOOKS: + bookAiService.handleAiStartMessage(user, AI_SUGGEST); + break; + case FILTER_BOOKS: + bookAiService.handleAiStartMessage(user, AI_FILTER);; + break; default: if (creationCache != null && creationCache.getCreationState() != null) { // Handle book creation states diff --git a/src/main/java/ru/cathub/telegabot/service/impl/TelegramBotServiceImpl.java b/src/main/java/ru/cathub/telegabot/service/impl/TelegramBotServiceImpl.java index ce8a2be..0acef1b 100644 --- a/src/main/java/ru/cathub/telegabot/service/impl/TelegramBotServiceImpl.java +++ b/src/main/java/ru/cathub/telegabot/service/impl/TelegramBotServiceImpl.java @@ -21,6 +21,7 @@ public class TelegramBotServiceImpl implements TelegramBotService { private final BookManageService bookManageService; private final ProfileService profileService; private final UserRepository userRepository; + private final BookAiServiceImpl bookAiServiceImpl; @Override public void processInput(BotUser botUser, String text) throws ServiceException { @@ -61,6 +62,9 @@ public class TelegramBotServiceImpl implements TelegramBotService { case EDIT_PROFILE: profileService.handleProfileUpdate(botUser, text); break; + case AI_FILTER,AI_SUGGEST: + bookAiServiceImpl.processAiRequest(botUser,text,botUser.getWorkingMode()); + break; } } } diff --git a/src/main/java/ru/cathub/telegabot/utils/Constants.java b/src/main/java/ru/cathub/telegabot/utils/Constants.java index ec3356f..7547f7c 100644 --- a/src/main/java/ru/cathub/telegabot/utils/Constants.java +++ b/src/main/java/ru/cathub/telegabot/utils/Constants.java @@ -13,7 +13,9 @@ public class Constants { public static final String LIST_BOOKS = "Список книг"; public static final String BACK = "Назад"; public static final String EDIT_BOOKS = "Редактировать книги"; - + public static final String RECOMMEND_BOOKS = "Рекомендации книг"; + + public static final String FILTER_BOOKS = "Фильтр по прочитанным"; // Cache names public static final String BOOK_CACHE_NAME = "bookCache"; public static final String BOOK_CACHE_LIST = "bookListCache"; @@ -38,4 +40,11 @@ public class Constants { public static final String ERROR_DELETE_BOOKS = "❌ Ошибка при удвлении книги"; public static final String ERROR_NO_ACTION = "❌ Нет текущего действия. Выберите действие из меню или перейдите в начальное меню командой /start"; public static final String ERROR_INVALID_DATE_FORMAT = "Неверный формат даты. Используйте ДД.ММ.ГГГГ"; + + // AI + public static final String AI_FILTER_GENRE = "Отфильтруй книги по жанру комедия"; + public static final String AI_FILTER_RATING = "Отфильтруй книги по по рейтингу больше 8"; + + public static final String AI_SUGGEST_SIMILAR = "Предложи похожие книги"; + public static final String AI_SUGGEST_GENRE = "Предложи еше книги в жанре фентези"; }