Всем привет! Меня зовут Шалико, я 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, идеи, вопросы, предложения.
