diff --git a/src/main/java/dev/struchkov/example/bot/conf/CustomEventDispatching.java b/src/main/java/dev/struchkov/example/bot/conf/CustomEventDispatching.java new file mode 100644 index 0000000..b75bdb1 --- /dev/null +++ b/src/main/java/dev/struchkov/example/bot/conf/CustomEventDispatching.java @@ -0,0 +1,62 @@ +package dev.struchkov.example.bot.conf; + +import dev.struchkov.godfather.main.domain.EventContainer; +import dev.struchkov.godfather.main.domain.content.Mail; +import dev.struchkov.godfather.simple.context.service.EventDispatching; +import dev.struchkov.godfather.simple.context.service.EventHandler; +import dev.struchkov.godfather.simple.core.EventDispatchingImpl; +import dev.struchkov.godfather.simple.domain.BoxAnswer; +import dev.struchkov.godfather.telegram.main.context.MailPayload; +import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending; +import org.springframework.stereotype.Component; + +import java.util.List; + +import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN; + +@Component +public class CustomEventDispatching extends EventDispatchingImpl implements EventDispatching { + + private final TelegramSending telegramSending; + private final AppProperty appProperty; + + public CustomEventDispatching(List eventProviders, TelegramSending telegramSending, AppProperty appProperty) { + super(eventProviders); + this.telegramSending = telegramSending; + this.appProperty = appProperty; + } + + @Override + public void dispatch(EventContainer event) { + if (Mail.class.equals(event.getType())) { + final Mail mail = (Mail) event.getObject(); + final String fromPersonId = mail.getFromPersonId(); + if (appProperty.getTelegramIds().contains(fromPersonId)) { + super.dispatch(event); + } else { + final StringBuilder messageText = new StringBuilder("\uD83D\uDEA8 *Attempted unauthorized access to the bot*") + .append("\n-- -- -- -- --\n"); + + mail.getPayLoad(MailPayload.USERNAME) + .ifPresent(username -> messageText.append("\uD83E\uDDB9\u200D♂️: @").append(username)); + + messageText.append("\n") + .append("\uD83D\uDCAC: ").append(mail.getText()); + + for (String adminTelegramId : appProperty.getAdminTelegramIds()) { + telegramSending.send( + BoxAnswer.builder() + .recipientPersonId(adminTelegramId) + .message(messageText.toString()) + .payload(ENABLE_MARKDOWN) + .build() + ); + } + + } + } else { + super.dispatch(event); + } + } + +} diff --git a/src/main/java/dev/struchkov/example/bot/service/PersonalChatService.java b/src/main/java/dev/struchkov/example/bot/service/PersonalChatService.java index abb8b99..c7e38dd 100644 --- a/src/main/java/dev/struchkov/example/bot/service/PersonalChatService.java +++ b/src/main/java/dev/struchkov/example/bot/service/PersonalChatService.java @@ -1,21 +1,32 @@ package dev.struchkov.example.bot.service; import dev.struchkov.example.bot.conf.AppProperty; +import dev.struchkov.haiti.context.exception.NotFoundException; import dev.struchkov.openai.context.ChatGptService; import dev.struchkov.openai.domain.chat.ChatInfo; import dev.struchkov.openai.domain.chat.CreateChat; -import dev.struchkov.openai.domain.chat.UpdateChat; import org.springframework.stereotype.Service; +import java.util.HashMap; import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException; + @Service public class PersonalChatService { + public static final String DEFAULT_CHAT_NAME = "DEFAULT"; + private final ChatGptService chatGptService; - private final Map chatDefaultContext = new ConcurrentHashMap<>(); - private final Map chatMap = new ConcurrentHashMap<>(); + + // ключ это идентификатор пользователя, значение это название чата + private final Map currentChatMap = new ConcurrentHashMap<>(); + + // первый ключ это идентификатор пользователя. второй это название чата + private final Map> chatMap = new ConcurrentHashMap<>(); public PersonalChatService( AppProperty appProperty, @@ -24,39 +35,82 @@ public class PersonalChatService { this.chatGptService = chatGptService; appProperty.getTelegramIds().forEach( telegramId -> { - final ChatInfo newChat = this.chatGptService.createChat( - CreateChat.builder().build() - ); - chatMap.put(telegramId, newChat); + final ChatInfo defaultChat = this.chatGptService.createChat(CreateChat.builder().build()); + final HashMap personChats = new HashMap<>(); + personChats.put(DEFAULT_CHAT_NAME, defaultChat); + chatMap.put(telegramId, personChats); + currentChatMap.put(telegramId, DEFAULT_CHAT_NAME); } ); } - public ChatInfo getChatByPersonId(String personId) { - return chatMap.get(personId); - } - - public ChatInfo recreateChat(String personId) { - final ChatInfo chatInfo = chatMap.get(personId); - chatGptService.closeChat(chatInfo.getChatId()); - final ChatInfo newChat = chatGptService.createChat( - CreateChat.builder() - .systemBehavior(chatDefaultContext.get(personId)) - .build() - ); - chatMap.put(personId, newChat); + public ChatInfo createChat(String personId, String chatName) { + if (existChat(personId, chatName)) { + closeChat(personId, chatName, DEFAULT_CHAT_NAME); + } + final ChatInfo newChat = chatGptService.createChat(CreateChat.builder().build()); + chatMap.get(personId).put(chatName, newChat); return newChat; } - public void setBehavior(String fromPersonId, String behavior) { - chatDefaultContext.put(fromPersonId, behavior); - final ChatInfo chatInfo = chatMap.get(fromPersonId); - chatGptService.updateChat( - UpdateChat.builder() - .chatId(chatInfo.getChatId()) - .systemBehavior(behavior) - .build() - ); + public String getCurrentChatName(String personId) { + return currentChatMap.get(personId); + } + + public ChatInfo getCurrentChat(String personId) { + final String currentChatName = getCurrentChatName(personId); + return chatMap.get(personId).get(currentChatName); + } + + public void setBehavior(String personId, String chatName, String behavior) { + final ChatInfo chatInfo = getChat(personId, chatName); + chatInfo.setSystemBehavior(behavior); + chatGptService.updateChat(chatInfo); + } + + public ChatInfo getChat(String personId, String chatName) { + return Optional.ofNullable(chatMap.get(personId).get(chatName)) + .orElseThrow(notFoundException("Chat with this name was not found")); + } + + public boolean existChat(String personId, String chatName) { + return chatMap.get(personId).containsKey(chatName); + } + + public void closeChat(String personId, String closeChatName, String switchChatName) { + if (DEFAULT_CHAT_NAME.equals(closeChatName)) { + throw new RuntimeException("You can't close the default chat room"); + } + + final ChatInfo chat = getChat(personId, closeChatName); + final ChatInfo switchChat = getChat(personId, switchChatName); + + currentChatMap.put(personId, switchChatName); + chatGptService.closeChat(chat.getChatId()); + chatMap.get(personId).remove(closeChatName); + } + + public void clearContext(String personId, String chatName) { + final ChatInfo chat = getChat(personId, chatName); + chatGptService.clearContext(chat.getChatId()); + } + + public void clearBehavior(String personId) { + final ChatInfo currentChat = getCurrentChat(personId); + currentChat.setSystemBehavior(null); + chatGptService.updateChat(currentChat); + } + + public void switchChat(String personId, String chatName) { + if (existChat(personId, chatName)) { + currentChatMap.put(personId, chatName); + } else { + throw new NotFoundException("Chat with the name {0} not found", chatName); + } + } + + public Set getAllChatName(String personId) { + return chatMap.get(personId).keySet(); } } diff --git a/src/main/java/dev/struchkov/example/bot/unit/BehaviorUnit.java b/src/main/java/dev/struchkov/example/bot/unit/BehaviorUnit.java index 3106112..3fa0d0e 100644 --- a/src/main/java/dev/struchkov/example/bot/unit/BehaviorUnit.java +++ b/src/main/java/dev/struchkov/example/bot/unit/BehaviorUnit.java @@ -1,6 +1,5 @@ package dev.struchkov.example.bot.unit; -import dev.struchkov.example.bot.conf.AppProperty; import dev.struchkov.example.bot.service.PersonalChatService; import dev.struchkov.example.bot.util.Cmd; import dev.struchkov.example.bot.util.UnitName; @@ -12,33 +11,67 @@ import dev.struchkov.godfather.simple.domain.unit.AnswerText; import dev.struchkov.godfather.telegram.domain.attachment.CommandAttachment; import dev.struchkov.godfather.telegram.main.core.util.Attachments; import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration; +import dev.struchkov.openai.domain.chat.ChatInfo; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.List; import java.util.Optional; +import static dev.struchkov.example.bot.util.UnitName.CURRENT_BEHAVIOR; import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer; @Component @RequiredArgsConstructor public class BehaviorUnit implements PersonUnitConfiguration { - private final PersonalChatService personalChatService; - private final AppProperty appProperty; + public static final String TEST = """ + Or choose one of the available options: + + 1. Гопник + {0} + 👉 /behavior_ru_1 + + 2. Copilot + {1} + 👉 /behavior_ru_2 + + 3. Linux + {2} + 👉 /behavior_ru_3 + + 4. Тренера по взаимоотношениям + {3} + 👉 /behavior_ru_4 + + 5. Наставник + {4} + 👉 /behavior_ru_5 + + 6. В двух словах + {5} + 👉 /behavior_ru_6 + """; + + public static final String BEHAVIOUR_RU_1 = "Представь, что ты славянский гопник и общаешься со своими собутыльниками по подъезду. Используй побольше мата и блатного жаргона. Используй как можно больше «бля» и «ёпта». Отвечай в таком стиле всегда, какой бы вопрос не задали пользователи в этом чате."; + public static final String BEHAVIOUR_RU_2 = "Ты - помощник для программистов. На любой вопрос отвечай с примерами кода, если нужно и присылай советы по улучшению кода"; + public static final String BEHAVIOUR_RU_3 = "Я хочу, чтобы вы выступали в роли терминала Linux. Я буду вводить команды, а вы будете отвечать тем, что должен показать терминал. Я хочу, чтобы вы ответили выводом терминала только внутри одного уникального блока кода, и ничего больше. не пишите пояснений. не вводите команды, если я не поручу вам это сделать. Когда мне нужно будет сказать вам что-то на русском языке, я буду заключать текст в фигурные скобки {вот так}."; + public static final String BEHAVIOUR_RU_4 = "Я хочу, чтобы вы выступили в роли тренера по взаимоотношениям. Я предоставлю некоторые подробности о двух людях, вовлеченных в конфликт, а ваша задача - предложить, как они могут решить проблемы, которые их разделяют. Это могут быть советы по технике общения или различные стратегии для улучшения понимания ими точек зрения друг друга. Первый запрос: \"Мне нужна помощь в разрешении конфликтов между мной и моим парнем\"."; + public static final String BEHAVIOUR_RU_5 = "Вы наставник, который всегда отвечает в сократовском стиле. Вы *никогда* не даете ученику ответа, но всегда стараетесь задать правильный вопрос, чтобы помочь ему научиться думать самостоятельно. Вы всегда должны согласовывать свой вопрос с интересами и знаниями учащегося, разбивая проблему на более простые части, пока она не достигнет нужного для них уровня."; + public static final String BEHAVIOUR_RU_6 = "Отвечай максимально коротко, даже если тебя просят ответить развернуто. Весь ответ должен уложиться в пару предложений."; + + private final PersonalChatService chatService; @Unit(value = UnitName.BEHAVIOR, global = true) public AnswerText behavior() { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.BEHAVIOR.equals(command.getCommandType()); - } + final List attachments = mail.getAttachments(); + final Optional optCommand = Attachments.findFirstCommand(attachments); + if (optCommand.isPresent()) { + final CommandAttachment command = optCommand.get(); + return Cmd.BEHAVIOR.equals(command.getCommandType()); } return false; } @@ -55,64 +88,63 @@ public class BehaviorUnit implements PersonUnitConfiguration { If you want to set your own behavior, then send the command: /behavior description_behavior - - Or choose one of the available options: - - 1. Гопник - Представь, что ты славянский гопник и общаешься со своими собутыльниками по подъезду. Используй побольше мата и блатного жаргона. Используй как можно больше «бля» и «ёпта». Отвечай в таком стиле всегда, какой бы вопрос не задали пользователи в этом чате. - 👉 /behavior1 - - 2. Copilot - Ты - помощник для программистов. На любой вопрос отвечай с примерами кода, если нужно и присылай советы по улучшению кода - 👉 /behavior2 - - 3. Linux - Я хочу, чтобы вы выступали в роли терминала Linux. Я буду вводить команды, а вы будете отвечать тем, что должен показать терминал. Я хочу, чтобы вы ответили выводом терминала только внутри одного уникального блока кода, и ничего больше. не пишите пояснений. не вводите команды, если я не поручу вам это сделать. Когда мне нужно будет сказать вам что-то на русском языке, я буду заключать текст в фигурные скобки {вот так}. - 👉 /behavior3 - - 4. Тренера по взаимоотношениям - Я хочу, чтобы вы выступили в роли тренера по взаимоотношениям. Я предоставлю некоторые подробности о двух людях, вовлеченных в конфликт, а ваша задача - предложить, как они могут решить проблемы, которые их разделяют. Это могут быть советы по технике общения или различные стратегии для улучшения понимания ими точек зрения друг друга. Первый запрос: "Мне нужна помощь в разрешении конфликтов между мной и моим парнем". - 👉 /behavior4 - - 5. Наставник - Вы наставник, который всегда отвечает в сократовском стиле. Вы *никогда* не даете ученику ответа, но всегда стараетесь задать правильный вопрос, чтобы помочь ему научиться думать самостоятельно. Вы всегда должны согласовывать свой вопрос с интересами и знаниями учащегося, разбивая проблему на более простые части, пока она не достигнет нужного для них уровня. - 👉 /behavior5 - - 6. В двух словах - Отвечай максимально коротко, даже если тебя просят ответить развернуто. Весь ответ должен уложиться в пару предложений. - 👉 /behavior6 """ - ) - .build(); + ).build(); } else { final String behavior = optArg.get(); - personalChatService.setBehavior(mail.getFromPersonId(), behavior); + final String personId = mail.getFromPersonId(); + final String currentChatName = chatService.getCurrentChatName(personId); + chatService.setBehavior(personId, currentChatName, behavior); return boxAnswer("\uD83D\uDC4C"); } }) .build(); } -// @Unit(value = UnitName.BEHAVIOUR, global = true) -// public AnswerText behaviour1() { -// return AnswerText.builder() -// .triggerCheck( -// mail -> { -// if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { -// final List attachments = mail.getAttachments(); -// final Optional optCommand = Attachments.findFirstCommand(attachments); -// if (optCommand.isPresent()) { -// final CommandAttachment command = optCommand.get(); -// return Cmd.BEHAVIOUR_1.equals(command.getCommandType()); -// } -// } -// return false; -// } -// ) -// .answer(() -> { -// -// }) -// .build(); -// } + @Unit(value = UnitName.CLEAR_BEHAVIOR, global = true) + public AnswerText clearBehavior() { + return AnswerText.builder() + .triggerCheck( + mail -> { + final List attachments = mail.getAttachments(); + final Optional optCommand = Attachments.findFirstCommand(attachments); + if (optCommand.isPresent()) { + final CommandAttachment command = optCommand.get(); + return Cmd.CLEAR_BEHAVIOR.equals(command.getCommandType()); + } + return false; + } + ) + .answer(mail -> { + chatService.clearBehavior(mail.getFromPersonId()); + return boxAnswer("Behavior successfully cleared"); + }) + .build(); + } + + @Unit(value = CURRENT_BEHAVIOR, global = true) + public AnswerText currentBehavior() { + return AnswerText.builder() + .triggerCheck( + mail -> { + final List attachments = mail.getAttachments(); + final Optional optCommand = Attachments.findFirstCommand(attachments); + if (optCommand.isPresent()) { + final CommandAttachment command = optCommand.get(); + return Cmd.CURRENT_BEHAVIOR.equals(command.getCommandType()); + } + return false; + } + ) + .answer(mail -> { + final ChatInfo currentChat = chatService.getCurrentChat(mail.getFromPersonId()); + final String systemBehavior = currentChat.getSystemBehavior(); + if (systemBehavior != null && !"".equals(systemBehavior)) { + return boxAnswer(systemBehavior); + } + return boxAnswer("The behavior for this chat is not set"); + }) + .build(); + } } diff --git a/src/main/java/dev/struchkov/example/bot/unit/ChatSettingUnit.java b/src/main/java/dev/struchkov/example/bot/unit/ChatSettingUnit.java new file mode 100644 index 0000000..2d2bc42 --- /dev/null +++ b/src/main/java/dev/struchkov/example/bot/unit/ChatSettingUnit.java @@ -0,0 +1,130 @@ +package dev.struchkov.example.bot.unit; + +import dev.struchkov.example.bot.service.PersonalChatService; +import dev.struchkov.example.bot.util.Cmd; +import dev.struchkov.example.bot.util.UnitName; +import dev.struchkov.godfather.main.domain.annotation.Unit; +import dev.struchkov.godfather.main.domain.content.Mail; +import dev.struchkov.godfather.simple.domain.BoxAnswer; +import dev.struchkov.godfather.simple.domain.unit.AnswerText; +import dev.struchkov.godfather.telegram.domain.attachment.CommandAttachment; +import dev.struchkov.godfather.telegram.main.core.util.Attachments; +import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.text.MessageFormat; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer; + +@Component +@RequiredArgsConstructor +public class ChatSettingUnit implements PersonUnitConfiguration { + + private final PersonalChatService chatService; + + @Unit(value = UnitName.CHAT, global = true) + public AnswerText chat() { + return AnswerText.builder() + .triggerCheck( + mail -> { + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.CHAT.equals(commandAttachment.getCommandType())).isPresent(); + } + ) + .answer( + mail -> { + final String personId = mail.getFromPersonId(); + final CommandAttachment command = Attachments.findFirstCommand(mail.getAttachments()).orElseThrow(); + final Optional optArg = command.getArg(); + if (optArg.isPresent()) { + final String chatName = optArg.get(); + final boolean isExistChat = chatService.existChat(personId, chatName); + if (!isExistChat) { + chatService.createChat(personId, chatName); + } + chatService.switchChat(personId, chatName); + return boxAnswer("Chat successfully switched"); + } else { + final Set chatNames = chatService.getAllChatName(personId); + final String chatList; + if (chatNames.size() > 1) { + chatList = "\n\nYour chats:\n" + chatNames.stream() + .filter(name -> !"DEFAULT".equals(name)) + .collect(Collectors.joining("\n• ", "• ", "")); + } else { + chatList = ""; + } + + final String message = MessageFormat.format( + """ + Chats allow you to have multiple conversations with different discussion contexts. + + To create a new chat room or switch to an existing one, use the + + /chat chat_name{0} + """, + chatList + ); + return BoxAnswer.builder() + .message(message) + .build(); + } + } + ) + .build(); + } + + @Unit(value = UnitName.CURRENT_CHAT, global = true) + public AnswerText getCurrentChatName() { + return AnswerText.builder() + .triggerCheck( + mail -> { + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.CURRENT_CHAT.equals(commandAttachment.getCommandType())).isPresent(); + } + ) + .answer( + mail -> { + final String currentChatName = chatService.getCurrentChatName(mail.getFromPersonId()); + return BoxAnswer.builder() + .message("Current chat name: " + currentChatName) + .build(); + + } + ) + .build(); + } + + @Unit(value = UnitName.CLOSE_CHAT, global = true) + public AnswerText closeChat() { + return AnswerText.builder() + .triggerCheck( + mail -> { + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.CLOSE_CHAT.equals(commandAttachment.getCommandType())).isPresent(); + } + ) + .answer( + mail -> { + final String personId = mail.getFromPersonId(); + final CommandAttachment command = Attachments.findFirstCommand(mail.getAttachments()).orElseThrow(); + final Optional optArg = command.getArg(); + if (optArg.isPresent()) { + final String name = optArg.get(); + chatService.closeChat(personId, name, PersonalChatService.DEFAULT_CHAT_NAME); + return boxAnswer("Chat has been successfully closed. You have returned to the default chat room!"); + } else { + final String currentChatName = chatService.getCurrentChatName(personId); + chatService.closeChat(personId, currentChatName, PersonalChatService.DEFAULT_CHAT_NAME); + return boxAnswer("Chat has been successfully closed. You have returned to the default chat room!"); + } + } + ) + .build(); + } + +} diff --git a/src/main/java/dev/struchkov/example/bot/unit/PersonalChatGPTUnit.java b/src/main/java/dev/struchkov/example/bot/unit/PersonalChatGPTUnit.java index 0d53e7f..95eefa0 100644 --- a/src/main/java/dev/struchkov/example/bot/unit/PersonalChatGPTUnit.java +++ b/src/main/java/dev/struchkov/example/bot/unit/PersonalChatGPTUnit.java @@ -16,7 +16,6 @@ import dev.struchkov.godfather.telegram.domain.ClientBotCommand; import dev.struchkov.godfather.telegram.domain.attachment.ButtonClickAttachment; import dev.struchkov.godfather.telegram.domain.attachment.CommandAttachment; import dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard; -import dev.struchkov.godfather.telegram.main.context.MailPayload; import dev.struchkov.godfather.telegram.main.core.util.Attachments; import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending; import dev.struchkov.godfather.telegram.simple.context.service.TelegramService; @@ -64,6 +63,21 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { .description("help in use") .build(), + ClientBotCommand.builder() + .key(Cmd.CHAT) + .description("Create or toggle a chat room") + .build(), + + ClientBotCommand.builder() + .key(Cmd.CLOSE_CHAT) + .description("Close the current chat.") + .build(), + + ClientBotCommand.builder() + .key(Cmd.CURRENT_CHAT) + .description("Returns the name of the current chat") + .build(), + ClientBotCommand.builder() .key(Cmd.CLEAR_CONTEXT) .description("Clears the discussion context. Start a conversation from the beginning.") @@ -79,6 +93,16 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { .description("Allows you to set the initial behavior of ChatGPT.") .build(), + ClientBotCommand.builder() + .key(Cmd.CURRENT_BEHAVIOR) + .description("Returns the current behavior description for the chat") + .build(), + + ClientBotCommand.builder() + .key(Cmd.CLEAR_BEHAVIOR) + .description("Clears the behavior settings for the current chat") + .build(), + ClientBotCommand.builder() .key(Cmd.SUPPORT_DEV) .description("Support project development.") @@ -86,41 +110,12 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { )); } - @Unit(value = UnitName.ACCESS_ERROR, main = true) - public AnswerText accessError() { - return AnswerText.builder() - .triggerCheck(mail -> !appProperty.getTelegramIds().contains(mail.getFromPersonId())) - .answer(message -> { - final StringBuilder messageText = new StringBuilder("\uD83D\uDEA8 *Attempted unauthorized access to the bot*") - .append("\n-- -- -- -- --\n"); - - message.getPayLoad(MailPayload.USERNAME) - .ifPresent(username -> messageText.append("\uD83E\uDDB9\u200D♂️: @").append(username)); - - messageText.append("\n") - .append("\uD83D\uDCAC: ").append(message.getText()); - - return BoxAnswer.builder() - .recipientPersonId(appProperty.getAdminTelegramIds().get(0)) - .message(messageText.toString()) - .payload(ENABLE_MARKDOWN) - .build(); - }) - .build(); - } - - @Unit(value = GPT_UNIT, global = true) + @Unit(value = GPT_UNIT, main = true, global = true) public AnswerText chatGpt() { return AnswerText.builder() - .triggerCheck(mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final Optional firstCommand = Attachments.findFirstCommand(mail.getAttachments()); - return firstCommand.isEmpty(); - } - return false; - }) + .triggerCheck(mail -> Attachments.findFirstCommand(mail.getAttachments()).isEmpty()) .answer(message -> { - final ChatInfo chatInfo = personalChatService.getChatByPersonId(message.getFromPersonId()); + final ChatInfo chatInfo = personalChatService.getCurrentChat(message.getFromPersonId()); final long countMessages = chatGptService.getCountMessages(chatInfo.getChatId()); final StringBuilder builder = new StringBuilder(); @@ -154,19 +149,15 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.CLEAR_CONTEXT.equals(command.getCommandType()); - } - } - return false; + final List attachments = mail.getAttachments(); + final Optional optCommand = Attachments.findFirstCommand(attachments); + return optCommand.filter(commandAttachment -> Cmd.CLEAR_CONTEXT.equals(commandAttachment.getCommandType())).isPresent(); } ) .answer(message -> { - personalChatService.recreateChat(message.getFromPersonId()); + final String personId = message.getFromPersonId(); + final String currentChatName = personalChatService.getCurrentChatName(personId); + personalChatService.clearContext(personId, currentChatName); return boxAnswer("\uD83E\uDDF9 Discussion context cleared successfully"); }) .build(); @@ -177,15 +168,8 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.START.equals(command.getCommandType()); - } - } - return false; + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.START.equals(commandAttachment.getCommandType())).isPresent(); } ) .answer(message -> { @@ -216,15 +200,8 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.PROMPT.equals(command.getCommandType()); - } - } - return false; + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.PROMPT.equals(commandAttachment.getCommandType())).isPresent(); } ) .answer( @@ -272,19 +249,15 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.SUPPORT_DEV.equals(command.getCommandType()); - } + final List attachments = mail.getAttachments(); + final Optional optCommand = Attachments.findFirstCommand(attachments); + if (optCommand.isPresent()) { + return Cmd.SUPPORT_DEV.equals(optCommand.get().getCommandType()); + } - final Optional optClick = Attachments.findFirstButtonClick(attachments); - if (optClick.isPresent()) { - final ButtonClickAttachment click = optClick.get(); - return Cmd.SUPPORT_DEV.equals(click.getRawCallBackData()); - } + final Optional optClick = Attachments.findFirstButtonClick(attachments); + if (optClick.isPresent()) { + return Cmd.SUPPORT_DEV.equals(optClick.get().getRawCallBackData()); } return false; } @@ -320,15 +293,8 @@ public class PersonalChatGPTUnit implements PersonUnitConfiguration { return AnswerText.builder() .triggerCheck( mail -> { - if (appProperty.getTelegramIds().contains(mail.getFromPersonId())) { - final List attachments = mail.getAttachments(); - final Optional optCommand = Attachments.findFirstCommand(attachments); - if (optCommand.isPresent()) { - final CommandAttachment command = optCommand.get(); - return Cmd.HELP.equals(command.getCommandType()); - } - } - return false; + final Optional optCommand = Attachments.findFirstCommand(mail.getAttachments()); + return optCommand.filter(commandAttachment -> Cmd.HELP.equals(commandAttachment.getCommandType())).isPresent(); } ) .answer(() -> boxAnswer(""" diff --git a/src/main/java/dev/struchkov/example/bot/util/Cmd.java b/src/main/java/dev/struchkov/example/bot/util/Cmd.java index 0886600..c42397e 100644 --- a/src/main/java/dev/struchkov/example/bot/util/Cmd.java +++ b/src/main/java/dev/struchkov/example/bot/util/Cmd.java @@ -12,7 +12,14 @@ public class Cmd { public static final String START = "start"; public static final String BALANCE = "balance"; + public static final String CHAT = "chat"; + public static final String CURRENT_CHAT = "current_chat"; + public static final String CLOSE_CHAT = "close_chat"; + public static final String BEHAVIOR = "behavior"; + public static final String CLEAR_BEHAVIOR = "clear_behavior"; + public static final String CURRENT_BEHAVIOR = "current_behavior"; + public static final String BEHAVIOR_1 = "behavior1"; public static final String BEHAVIOR_2 = "behavior2"; public static final String BEHAVIOR_3 = "behavior3"; @@ -20,5 +27,4 @@ public class Cmd { public static final String BEHAVIOR_5 = "behavior5"; public static final String BEHAVIOR_6 = "behavior6"; - } diff --git a/src/main/java/dev/struchkov/example/bot/util/UnitName.java b/src/main/java/dev/struchkov/example/bot/util/UnitName.java index fa4bc6a..311a4db 100644 --- a/src/main/java/dev/struchkov/example/bot/util/UnitName.java +++ b/src/main/java/dev/struchkov/example/bot/util/UnitName.java @@ -6,13 +6,20 @@ import lombok.experimental.UtilityClass; public class UnitName { public static final String GPT_UNIT = "GENERAL_MENU"; - public static final String CLEAR_CONTEXT = "CLEAR_CONTEXT"; public static final String HELP = "HELP"; public static final String PROMPT = "PROMPT"; public static final String ACCESS_ERROR = "ACCESS_ERROR"; public static final String SUPPORT = "SUPPORT"; public static final String START = "START"; + + public static final String CHAT = "CHAT"; + public static final String CURRENT_CHAT = "CURRENT_CHAT"; + public static final String CLOSE_CHAT = "CLOSE_CHAT"; + public static final String CLEAR_CONTEXT = "CLEAR_CONTEXT"; + public static final String BEHAVIOR = "BEHAVIOR"; + public static final String CURRENT_BEHAVIOR = "CURRENT_BEHAVIOR"; + public static final String CLEAR_BEHAVIOR = "CLEAR_BEHAVIOR"; public static final String BALANCE = "BALANCE"; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d4def67..5936360 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,7 @@ app: admin-telegram-ids: ${ADMIN_TELEGRAM_PERSON_ID} telegram-ids: ${TELEGRAM_PERSON_ID} - version: 0.0.1 + version: 0.1.0 telegram: bot: username: ${TELEGRAM_BOT_USERNAME}