Всем привет! Меня зовут Шалико, я Java-разработчик и часто создаю Telegram-ботов в своих pet-проектах.
Сегодня хочу рассказать вам про фреймворк, который я разработал, чтобы сильно упростить этот процесс.
Не спешите пролистывать статью - вам действительно может быть интересно, даже если вы не пишете Telegram-ботов каждый день.
Исходники проекта на GitHub
А ниже я расскажу, как это работает и почему вообще возникла идея фреймворка.
Зачем? Какие боли решаем?
У меня за плечами уже с десяток Telegram-ботов, но разработка каждого нового превращается в копипасту конфигурации, property-классов и жизненного цикла приложения из сервиса в сервис - эта рутина утомляет.
Мне захотелось упростить себе жизнь и заодно сделать крутой инструмент для других.
Кто-то спросит:
Наверняка есть уже готовые решения, зачем городить свой велосипед?
Я тоже так думал.
Но поиск Plug-and-Play фреймворков по GitHub не дал ничего, кроме проектов трёхлетней давности, которые уже не поддерживаются ни разработчиками, ни сообществом.
Поэтому я разработал Telegram Bot Spring Boot Starter - фреймворк, который:
минимизирует усилия для запуска простого бота;
имеет прозрачную архитектуру и легко расширяется;
управляет жизненным циклом за вас;
содержит готовые механизмы маршрутизации и обработки ошибок;
имеет единый и понятный пайплайн обработки апдейтов;
отлично интегрируется в Spring Boot-экосистему.
Описание фреймворка и его архитектура
Верхнеуровневая архитектура

В действительности сущностей немного больше чем здесь представлено, однако я не хочу вдаваться сильно в детали, чтобы не перегружать статью.
Общее описание
Ingress - абстракция, которая отвечает за получение Telegram-апдейтов;
Delivery - передает их дальше и может работать асинхронно, при любых ошибках происходит fallback на ExceptionHandler;
Interceptor - позволяет встроиться в цепочку обработки (фильтр, метрики и т.д.);
Dispatcher - определяет Router для использования;
Router - выбирает Handler на основе типа апдейта и его содержания;
Handler - содержит непосредственную бизнес-логику для конкретного апдейта;
NoMatchStrategy - fallback, если не смогли найти подходящий Router или Handler;
По умолчанию все реализации уже есть из коробки, но вы можете переопределить любой из этапов.
А что насчет API? Yet Another Telegram Bot API?
На самом деле нет никакой необходимости в ручной реализации Telegram Bot API.
Поэтому фреймворк я построил вокруг java-telegram-bot-api - надежная и популярная библиотека, которую многие используют в проде.
Однако я постарался максимально изолировать использование сущностей из этой библиотеки, чтобы потенциальный переезд на другие реализации Bot API был прост.
Небольшой пример
Ниже хочу привести простой пример, как можно быстро запустить бота, который умеет отвечать на /start и /help.
application.properties
telegram.bot.token=<ваш-токен>
Java-код
@SpringBootApplication
public class LongPollingSampleApplication {
public static void main(String[] args) {
SpringApplication.run(LongPollingSampleApplication.class, args);
}
}
@Component
public class StartCommandHandler implements CommandUpdateHandler {
private final TelegramBotExecutor telegramBotExecutor;
@Override
public void handle(Update update) {
SendMessage sendMessage = new SendMessage(update.message().from().id(), "Simple Hello!");
telegramBotExecutor.execute(sendMessage);
}
@Override
public Set<String> commands() {
return Set.of("/start", "/help");
}
}
Для маршрутизации plain-text сообщений и InlineQuery предусмотрены специальные правила, при помощи которых фреймворк может определить какой именно handler необходимо использовать.
Например, так может выглядеть обработка сообщения, которое содержит подстроку test:
@Component
public class TestMessageUpdateRule implements MessageUpdateRule {
private final TestMessageUpdateHandler updateHandler;
@Override
public Matcher<Message> matcher() {
return (m) -> m.text().toLowerCase().contains("test");
}
@Override
public UpdateHandler handler() {
return updateHandler;
}
}
@Component
public class TestMessageUpdateHandler implements MessageUpdateHandler {
private final TelegramBotExecutor telegramBotExecutor;
@Override
public void handle(Update update) {
SendMessage sendMessage = new SendMessage(update.message().chat().id(),
"Your 'test' message was successfully handled");
telegramBotExecutor.execute(sendMessage);
}
}
Более подробный пример вы можете увидеть здесь: telegram-bot-advanced-sample-long-polling
А что дальше?
Сейчас фреймворк полностью готов к использованию, а часть своих проектов я уже перевел на него.
Однако есть множество "хотелок", которые я еще не успел покрыть, вот самые первые на очереди:
модуль для работы с Apache Kafka;
модуль для observability;
модуль с машиной состояний + интеграция с БД;
маршрутизация других типов апдейтов;
Итог
В этом проекте я ставил себе цель - разработать фреймворк, который:
удобен для быстрого старта и простых ботов;
но при этом достаточно гибкий для серьезных проектов;
Послесловие
Проект открытый и развивается - приглашаю посмотреть
Спасибо, что уделили время статье!
Если вы попробуете фреймворк в работе — буду рад любой обратной связи:
issues, идеи, вопросы, предложения.
AdrianoVisoccini
О! Вот это прям спасибо. Сам делаю ботов на джаве по поводу и без и да, действительно надоело постоянно одно и то же делать! В следующий раз постараюсь вспомнить о вашем проекте