forked from Sanders/TelegaBot
Fix chat interactions
This commit is contained in:
@@ -2,7 +2,7 @@ package ru.cathub.telegabot.model;
|
||||
|
||||
public enum TextRole {
|
||||
DEFAULT("Ты книжный ассистент в Telegram-боте. Отвечай кратко, используй эмоджи, разметку Markdown (*для\n" +
|
||||
" выделения*, _для наклонного_)"),
|
||||
" выделения*, _для наклонного_). Отвечай ТОЛЬКО на русском языке. Дополнительно проверь что ответ точно на Русском языке."),
|
||||
REVIEWER("Анализируй текст как профессиональный редактор"),
|
||||
RECOMMENDER("Рекомендуй книги на основе предпочтений");
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import ru.cathub.telegabot.model.BookCreationCache;
|
||||
import ru.cathub.telegabot.model.TextRole;
|
||||
import ru.cathub.telegabot.repository.BookRepository;
|
||||
import ru.cathub.telegabot.model.BotUser;
|
||||
import ru.cathub.telegabot.repository.UserRepository;
|
||||
import ru.cathub.telegabot.service.*;
|
||||
import ru.cathub.telegabot.utils.Constants;
|
||||
|
||||
@@ -20,6 +21,7 @@ import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import static ru.cathub.telegabot.model.BookEditStateCache.BookEditState.*;
|
||||
import static ru.cathub.telegabot.utils.BookFormatUtils.escapeNonMarkdown;
|
||||
import static ru.cathub.telegabot.utils.Constants.*;
|
||||
|
||||
@Service
|
||||
@@ -32,6 +34,7 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
private final BookRepository bookRepository;
|
||||
private final BookCommonService bookCommonService;
|
||||
private final OpenRouterService openRouterService;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public void handleNewAddRequest(BotUser user, String text) {
|
||||
@@ -39,13 +42,13 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
BookCreationCache newCache = new BookCreationCache();
|
||||
newCache.setCreationState(BookCreationCache.CreationState.ADDING_TITLE);
|
||||
bookCacheService.updateCache(user.getId(), newCache);
|
||||
|
||||
|
||||
telegramClientService.sendMessageWithMarkdown(user, "*Введите название книги: \uD83D\uDCDA*", null);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
@Transactional
|
||||
public void handleExistingAddCache(BotUser user, String text) {
|
||||
BookCreationCache cache = bookCacheService.getCache(user.getId());
|
||||
|
||||
@@ -80,7 +83,7 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
bookCacheService.updateCache(user.getId(), cache);
|
||||
telegramClientService.sendMessage(user, "📅 Введите дату прочтения (в формате ДД.ММ.ГГГГ):");
|
||||
}
|
||||
|
||||
|
||||
case ADDING_DATE -> {
|
||||
Date readDate = parseDate(text.trim());
|
||||
cache.setReadDate(readDate);
|
||||
@@ -88,49 +91,36 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
|
||||
// Создаем и сохраняем книгу
|
||||
Book book = createBookFromCache(cache, user);
|
||||
bookRepository.save(book);
|
||||
|
||||
// Очищаем кэш
|
||||
bookCacheService.clearCache(user.getId());
|
||||
|
||||
// Отправляем подтверждение
|
||||
String message = String.format("✅ Книга успешно добавлена\\!\n\n%s",
|
||||
bookCommonService.formatBookDetails(book));
|
||||
String message = String.format("✅ Книга успешно добавлена\\!\n\n%s", bookCommonService.formatBookDetails(book));
|
||||
// Формируем статистику
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate endOfYear = LocalDate.of(today.getYear(), 12, 31);
|
||||
long weeksLeft = ChronoUnit.WEEKS.between(today, endOfYear);
|
||||
|
||||
int target = user.getBooksToRead() != null ? user.getBooksToRead() : 0;
|
||||
int read = user.getBooks() != null ? user.getBooks().size() : 0;
|
||||
BotUser freshUser = userRepository.findById(user.getId()).orElseThrow();
|
||||
int target = freshUser.getBooksToRead() != null ? freshUser.getBooksToRead() : 0;
|
||||
int read = freshUser.getBooks() != null ? freshUser.getBooks().size() : 0;
|
||||
int left = target - read;
|
||||
|
||||
String stats = String.format(
|
||||
"\n\n📊 *Статистика:*\n" +
|
||||
"⏳ До конца года: %d недель\n" +
|
||||
"🎯 Цель: %d книг\n" +
|
||||
"✅ Прочитано: %d\n" +
|
||||
"📖 Осталось: %d",
|
||||
weeksLeft, target, read, left > 0 ? left : 0
|
||||
);
|
||||
String stats = String.format("\n\n📊 *Статистика:*\n" + "⏳ До конца года: %d недель\n" + "🎯 Цель: %d книг\n" + "✅ Прочитано: %d\n" + "📖 Осталось: %d", weeksLeft, target, read, left > 0 ? left : 0);
|
||||
|
||||
telegramClientService.sendMessageWithMarkdown(user, message + stats);
|
||||
|
||||
bookRepository.save(book);
|
||||
|
||||
// Генерируем и отправляем поздравление
|
||||
try {
|
||||
String prompt = String.format("Придумай креативное поздравление с прочтением книги \"%s\". " +
|
||||
"Учитывай что пользователь поставил оценку %d/10. ",
|
||||
cache.getTitle(), cache.getRating());
|
||||
|
||||
String congrat = openRouterService.getChatResponse(
|
||||
prompt,
|
||||
TextRole.DEFAULT
|
||||
);
|
||||
|
||||
String prompt = String.format("Придумай креативное поздравление с прочтением книги \"%s\" от автора \"%s\". " + "Учитывай что пользователь поставил оценку %d/10. ", cache.getTitle(),cache.getAuthor(), cache.getRating());
|
||||
|
||||
|
||||
telegramClientService.sendMessageWithMarkdown(user, "🎉 *Поздравляю с прочтением!*\n\n" + congrat);
|
||||
String congrat = openRouterService.getChatResponse(prompt, TextRole.DEFAULT);
|
||||
|
||||
log.info("Congratulation generated: {}", congrat);
|
||||
telegramClientService.sendMessageWithMarkdown(user, "🎉 *Поздравляю с прочтением\\!*\n\n" + escapeNonMarkdown(congrat));
|
||||
} catch (Exception e) {
|
||||
log.error("Error generating congratulation for user {}", user.getId(), e);
|
||||
telegramClientService.sendMessage(user, "📚 Спасибо за добавление книги!");
|
||||
@@ -145,8 +135,7 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("Invalid rating format for user {}", user.getId(), e);
|
||||
telegramClientService.sendMessage(user, "❌ Ошибка: рейтинг должен быть числом от 0 до 10");
|
||||
}
|
||||
catch (ParseException e) {
|
||||
} catch (ParseException e) {
|
||||
log.error("Invalid date format for user {}", user.getId(), e);
|
||||
telegramClientService.sendMessage(user, "❌ Ошибка: дата должна быть в формате ДД.ММ.ГГГГ");
|
||||
} catch (Exception e) {
|
||||
@@ -171,12 +160,6 @@ public class BookCreationServiceImpl implements BookCreationService {
|
||||
}
|
||||
|
||||
private Book createBookFromCache(BookCreationCache cache, BotUser user) {
|
||||
return Book.builder()
|
||||
.title(cache.getTitle())
|
||||
.author(cache.getAuthor())
|
||||
.rating(cache.getRating())
|
||||
.readDate(cache.getReadDate())
|
||||
.botUser(user)
|
||||
.build();
|
||||
return Book.builder().title(cache.getTitle()).author(cache.getAuthor()).rating(cache.getRating()).readDate(cache.getReadDate()).botUser(user).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class TelegramClientServiceImps implements TelegramClientService {
|
||||
return telegramClient.execute(message);
|
||||
} catch (TelegramApiException e) {
|
||||
//logger.error("Ошибка отправки сообщения", e);
|
||||
throw new RuntimeException(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ public class BookFormatUtils {
|
||||
return text.replaceAll("([_*\\[\\]()~`>#+=|{}.!-])", "\\\\$1");
|
||||
}
|
||||
|
||||
public static String escapeNonMarkdown(String text) {
|
||||
return text.replaceAll("([().!-])", "\\\\$1");
|
||||
}
|
||||
|
||||
public static String formatDate(Date date) {
|
||||
if (date == null) {
|
||||
return "Не указана";
|
||||
|
||||
@@ -33,7 +33,7 @@ logging.level.org.springframework.cache=INFO
|
||||
|
||||
# OpenRouter AI
|
||||
openrouter.api.url=https://openrouter.ai/api/v1
|
||||
openrouter.api.model=deepseek/deepseek-r1-distill-qwen-32b
|
||||
openrouter.api.model=qwen/qwen-2.5-72b-instruct
|
||||
# Для безопасности лучше установить через переменную окружения:
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
@TestPropertySource(locations = "classpath:application.properties")
|
||||
@Disabled
|
||||
class TelegramBotApplicationTests {
|
||||
|
||||
@Value("${bot.token}")
|
||||
|
||||
@@ -38,7 +38,7 @@ class OpenRouterServiceIntegrationTest {
|
||||
when(restTemplate.postForEntity(anyString(), any(), eq(Map.class)))
|
||||
.thenReturn(new ResponseEntity<>(mockResponse, HttpStatus.OK));
|
||||
|
||||
String response = openRouterService.getChatResponse("Test message");
|
||||
String response = openRouterService.getSimpleResponse("Test message");
|
||||
assertEquals("Test response", response);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,6 @@ class OpenRouterServiceIntegrationTest {
|
||||
.thenThrow(new RestClientException("API error"));
|
||||
|
||||
assertThrows(OpenRouterException.class,
|
||||
() -> openRouterService.getChatResponse("Test message"));
|
||||
() -> openRouterService.getSimpleResponse("Test message"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class OpenRouterServiceLiveTest {
|
||||
assumeTrue(openRouterConfig.getKey() != null && !openRouterConfig.getKey().isBlank(),
|
||||
"OPENROUTER_API_KEY not set");
|
||||
|
||||
String response = openRouterService.getChatResponse("Hello in Russian");
|
||||
String response = openRouterService.getSimpleResponse("Hello in Russian");
|
||||
|
||||
assertNotNull(response);
|
||||
assertFalse(response.isBlank());
|
||||
|
||||
@@ -53,7 +53,7 @@ class OpenRouterServiceTest {
|
||||
when(restTemplate.postForEntity(anyString(), any(), eq(Map.class)))
|
||||
.thenReturn(new ResponseEntity<>(mockResponse, HttpStatus.OK));
|
||||
|
||||
String response = openRouterService.getChatResponse("Test message");
|
||||
String response = openRouterService.getSimpleResponse("Test message");
|
||||
assertEquals("Test response", response);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,6 @@ class OpenRouterServiceTest {
|
||||
.thenThrow(new RestClientException("API error"));
|
||||
|
||||
assertThrows(OpenRouterException.class,
|
||||
() -> openRouterService.getChatResponse("Test message"));
|
||||
() -> openRouterService.getSimpleResponse("Test message"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user