Реализация простого телеграм-бота
Работа с проектом
Работа с проектом будет выстроена аналогично остальным нашим курсам:
проект в Git репозитории, патчи для изменения проекта, ветка с готовым кодом и группа
поддержки в Telegram.
- По мере прохождения материала нужно будет последовательно применять в ветке master пронумерованные патчи (Apply patch) из архива патчей (патчи сделаны в JetBrains IDEA, лучше всего применять их в этой IDE или аналогах).
- После применения каждого патча следует делать коммит, чтобы было легче отслеживать изменения в git. Ветку patched можно использовать для разрешения конфликтов.
-
Переключиться в проекте на ветку patched c уже примененными патчами:
https://github.com/JavaOPs/ai-bot/tree/patched - По мере прохождения материала откатывать проект (Checkout Revision) на нужное место
Также можете настроить push проекта в свой Git
репозиторий
Проходя занятие вы смотрите проект - добавленный в него код, объяснения добавленного кода в занятии, запускаете и дебажите бота.
Таким образом вы быстро на практике усваиваете Telegram API и Java классы для удобной организации работы с ними в реальных проектах.
На проекте мы будем использовать последнюю LTS JDK 25 (скачать OpenJDK 25)
Создаем телеграм-бота
Создайте бота в @BotFather по инструкции (займет одну-две минуты).
Сохраните HTTP API Token созданного бота, он нам понадобится в приложении.
Сохраните HTTP API Token созданного бота, он нам понадобится в приложении.
Getting Started c telegrambots
Создадим простейшего телеграм бота на основе Java библиотеки TelegramBots
(библиотеки, которая имплементирует Telegram APIs)
по "getting-started" руководству.
Инициализация проекта: Getting Started with TelegramBots
-
В
pom.xmlк проекту подключены зависимости логирования logback-classic и утилитная библиотека для сокращения кода Lombok (используем аннотацию @Slf4j) - Класс проекта
AIBotреализует получение данных из бота (getUpdates API), используя Long polling.
После полученияUpdate, если он содержит сообщение с текстом, мы логируем текст в консоль. В Telegram APIs есть еще второй метод получения данных - WebHook. Из обсуждения статьи сравнения этих методов на Хабр:"Long polling подразумевает, что сервер не разрывает запрос в течение длительного времени (обычно это минута или 30 секунд), если нет новых событий для вас, но вернет их моментально, как только они появятся. Таким образом, вы выполняете очень мало запросов и получаете запросы моментально. Long polling, в отличие от webhook, не может быть бутылочным горлышком для вашего бота, потому что вы сами отправляете запрос на обновления к Telegram, когда готовы их обработать, и работает это максимально эффективно. В случае с webhook Telegram сам шлет вам запросы, что на пике может положить ваш сервер или заставить его обрабатывать запросы значительно медленнее, потому что у веб-серверов есть ограничения на максимальное количество открытых запросов одновременно. Более того, в случае с webhook 1 обновление = 1 запрос, то есть запросов будет гораздо больше, чем при использовании long polling, и на больших ботах это будет вызывать проблемы с производительностью. Если к этому добавить то, что для работы webhook нужно возиться с сертификатами и получить белый IP, я считаю использование long polling выигрышным в 100% случаев."
-
В классе
AIBotMainзамените"BOT_HTTP_API_Token"на токен вашего созданного бота -
Запустите
AIBotMain.
Перейдите в вашего созданного бота. Проверьте, что команда/startи любое ваше сообщение появляется в логе приложения
Отправка сообщений
На основе примера Simple echo bot сделаем отправку эха сообщения с учетом того,
что наш проект будет развиваться.
В ветке master примените патч 1_1_sendMessage из архива патчей
- TelegramBots имеет 2 реализации отправки сообщений: на основе библиотек OkHttp и Jetty. С учетом того, что в дальнейшем мы подключим Spring Boot, а он умеет работать с Jetty, сразу подключим зависимость Jetty HTTP client.
-
Добавим свои классы исключений: общий
AppExceptionиTelegramException. Впоследствии мы будем их дополнять. - Добавим утилитные классы-обертки для работы с telegrambots:
ClientHandlerдля отправкой сообщений черезJettyTelegramClientUpdateHandlerдля работы сUpdate. КодgetChatId/getFromвзять из раcширенной библиотеки telegrambots-abilities
-
Добавим конфигурацию логирования
/src/main/resources/logback.xml.
Классы проекта логируются с уровнемdebug, все остальное с уровнемinfo. - В классе
AIBotмы отправляем принятое сообщение с помощьюClientHandler.
При общении пользователя с ботомmessage.chatIdсовпадает сmessage.from.id.
Т.к.Userнам впоследствии пригодится, telegram_id получаем из него. - Токен бота нельзя хранить в репозитории (точно так же, как и другие креденшелы).
Вынесем его в переменную окружения
BOT_HTTP_API_TOKEN. При запуске следует или выставить его в системе (перезапустив IDEA) или задать в конфигурации запуска:
Форматирование сообщений
В Telegram API можно посылать сообщения в
обычном текстовом, HTML и Markdown форматах.
Попробуйте послать нашему боту сообщение с форматированием, например такое (в формате Markdown):
Приглашаем *Java-разработчиков на открытый курс* [Java AI Bot](https://javaops.ru/view/ai-bot)
*Разработка ИИ телеграм-бота с использованием TelegramBots + Spring AI* _Мы создадим с нуля телеграм-бот, который_:
🔥 Сохраняет состояние и работает с форматированными сообщениями
🔥 Интегрирован с Spring AI и ИИ чатом _ВЫ ПОЛУЧИТЕ_:
⚡️ Понимание принципов и опыт работы с [TelegramBots](https://github.com/rubenlagus/TelegramBots) + [Spring AI](https://spring.io/projects/spring-ai)
⚡️ Готовое полноценное приложение как основу для большого проекта
⚡️ Поддержку и живое общение в телеграм-группе с темами на каждое занятие *Ждем на нашем курсе!*
Ответ придет "as is", без форматирования. Научим наш бот отсылать форматированные сообщения.
Добавим в
Проверьте, что теперь отправляется сообщение с форматированием.
Теперь скопируйте-вставьте сообщение бота, пришедшее как эхо (или создаете новое средствами форматирования Telegram, выделив фрагмент):

Ответ придет снова без форматирования - в принимаемом сообщении Message с форматированием используются MessageEntity. Научим наш бот конвертировать принимаемое сообщения в формат Markdown.
ИИ-чат сгенерировал мне метод
Телеграм-бот «Java ассистент»
Попробуйте послать нашему боту сообщение с форматированием, например такое (в формате Markdown):
Приглашаем *Java-разработчиков на открытый курс* [Java AI Bot](https://javaops.ru/view/ai-bot)
*Разработка ИИ телеграм-бота с использованием TelegramBots + Spring AI* _Мы создадим с нуля телеграм-бот, который_:
🔥 Сохраняет состояние и работает с форматированными сообщениями
🔥 Интегрирован с Spring AI и ИИ чатом _ВЫ ПОЛУЧИТЕ_:
⚡️ Понимание принципов и опыт работы с [TelegramBots](https://github.com/rubenlagus/TelegramBots) + [Spring AI](https://spring.io/projects/spring-ai)
⚡️ Готовое полноценное приложение как основу для большого проекта
⚡️ Поддержку и живое общение в телеграм-группе с темами на каждое занятие *Ждем на нашем курсе!*
Ответ придет "as is", без форматирования. Научим наш бот отсылать форматированные сообщения.
В ветке master примените патч 1_2_sendMd из архива патчей
ClientHandler 3 разных метода отправки для всех форматов и используем в AIBot метод clientHandler.sendMd.Проверьте, что теперь отправляется сообщение с форматированием.
Теперь скопируйте-вставьте сообщение бота, пришедшее как эхо (или создаете новое средствами форматирования Telegram, выделив фрагмент):

Ответ придет снова без форматирования - в принимаемом сообщении Message с форматированием используются MessageEntity. Научим наш бот конвертировать принимаемое сообщения в формат Markdown.
В ветке master примените патч 1_3_getFormatting из архива патчей
ИИ-чат сгенерировал мне метод
UpdateHandler.recoverMarkdown, который переводит Message + MessageEntity
в формат Markdown. Подключим этот метод в AIBot. Теперь, когда бот принимает форматированное средствами Telegram сообщение, он преобразует его в формат Markdown и
мы снова получим от него форматированный ответ-эхо.
PS: преобразованный Markdown не будет работать, если оно форматирование накладывается, например Bold + Link или Bold + Italic).