Особенности создания телеграм-бота на Java
В статье пойдет разговор о том, что такое боты, для чего они используются, как работают и чем отличаются от обычных аккаунтов. Также рассмотрим порядок создания телеграм-бота на «Джава».
Ботами (bot) и чат ботами (chat bots) называют специальные аккаунты в Телеграмм, используемые для автоматической обработки и отправки сообщений. На практике пользователи взаимодействуют с ботами посредством сообщений, которые они отправляют как через обычные, так и через групповые чаты. Бот работает по определенной логике — она контролируется с помощью HTTPS-запросов к специальному API для ботов от Телеграм.
Возможности ботов
Приведем несколько классических примеров применения ботов в Телеграмм:
- Утилиты и инструменты. Телеграм-бот может переводить тексты, отображать актуальную погоду, предупреждать о каких-либо предстоящих событиях, использоваться для проведения опросов.
- Интеграция с сервисами. Бота можно использовать для отправки комментариев либо уведомлений, управления «умным домом».
- Игры (как одно-, так и многопользовательские). Бот без проблем поиграет с вами в шахматы/шашки, проведет викторину и т. п.
- Социальные сервисы. При необходимости специальный бот найдет вам собеседника, взяв за основу для поиска ваши интересы и увлечения.
- Все остальное. Это «все остальное» ограничивается лишь вашей фантазией. На деле вы можете запрограммировать бота практически для чего угодно. Однако стоит понимать, что он все равно останется ботом, а значит, не сможет помыть посуду вместо вас.
Если резюмировать вышеперечисленное одним предложением, то бот в Телеграм умеет оставлять комментарии к записям и постам, переводить тексты, искать информацию и аудио/видеоданные, спрашивать и отвечать на вопросы, подключаться к сети, обходить блокировки роутеров и сервисов, создавать чаты для общения, транслировать презентации и т. д. — всего не перечислишь.
Как функционируют боты?
Боты — особые аккаунты, по сути, представляющие собой интерфейс к вашему сервису, работающему на удаленном сервере. Плюс в том, что для создания бота вам совершенно не обязательно изучать низкоуровневые технологии, так как все взаимодействие основано на обычном HTTPS-интерфейсе с упрощенными методами API — его называют Bot API .
В реальности вы можете создать бота в Телеграмм с помощью… бота. Для этого потребуется написать пользователю @BotFather , а потом следовать его инструкциям. После создания вы получите специальный ключ авторизации (токен). Выполнить необходимые настройки можно будет в разделе документации Bot API .

Особенности создания бота с помощью Java
Если вы не ищете легких путей, хотите прокачаться в Java и привыкли все творить своими руками, вы можете написать бота, используя язык программирования Java («Джава», «Ява»). Ниже рассмотрим один из возможных алгоритмов действий.
Пишем бот на Java
На деле написать бота для Телеграмм, используя Java, не так уже сложно. Рассмотрим пример создания бота посредством Webhook.

Общая последовательность действий будет следующей:
- Открываем «Эклипс», создаем новый Java-проект.
- Находим и загружаем базу, необходимую для создания Telegram-ботов.
- Импортируем загруженную библиотеку в проект.
- Создаем класс test.SimpleBot со следующим содержимым:
— открытие веб-браузера, переход по ссылке: https://telegram.me/botfather;
— нажатие кнопки «Send message»;
— выбор BotFather в Телеграме;
— ввод имени бота на Webhook.
Также надо будет придумать имя пользователя для вновь созданного бота. Тут главное, чтобы это имя было уникальным. После ввода имени надо будет нажать кнопку подтверждения, в результате чего появится сообщение об успешной конфигурации. Обратите внимание, что после «Use this token to access the HTTP API:» выведется ваш токен, который надо будет ввести в требуемом месте.
- Переходим в «Эклипс», запускаем бота.
- В адресной строке веб-браузера набираем https://telegram.me/имя_вашего_бота (это необходимо для тестирования работоспособности).
- Нажимаем «Send message».
- Возвращаемся в Телеграм, выбираем созданного бота.
- Кликаем «Старт».
Все, Telegram-bot Webhook, написанный на «Джава», готов. На данном этапе на любое обращение робот должен отвечать что-то в стиле «Я не знаю, что ответить на это», однако эту фразу можно поменять путем дополнения базы.
Каковы плюсы Telegram-бота на Java
Можно перечислить ряд преимуществ такой реализации:
- Простота.
- Минимум выполняемых операций.
- Минимум требуемых знаний и умений.
В сети вы можете найти целый спектр уже готовых решений в виде программного кода, поэтому написать бота на Java будет не сложно. Вот, к примеру, полезное обучающее видео , где подробно рассказывается о том, как создать погодного бота на «Джава». Преимущество именно этого решения — легкость, доступность, простота создания. Дерзайте!
- https://stelegram.ru/faq/pravila-sozdaniya-telegramm-bota-na-java;
- https://tlgrm.ru/docs/bots.
Простой бот Telegram на Java с нуля

1970-01-01 в 0:00, admin , рубрики: Песочница
Важно для прочтения!
Если ты не против, то изучи ООП и Jav’y прежде, чем учить другие библиотеки. Ибо ты не будешь браться за физику, не выучив математику. Тут то же самое.
Сегодня мы будем писать простейшего бота Telegram, который будет отвечать на команды. Такая статья была, но писали бота на Питоне.
Почему я выбрал именно Jav’y
Java в плане ботов, серверов, плагинов да и вообще программ будет удобнее для меня.
1. Виртуальная машина хоть и долгая, но если обрабатывать события в несколько потоков, то будет работать быстро.(Вообще для многих серверов/мультиплеерных игр в одном потоке не всегда получится обрабатывать события, в Jav’e сделать это гораздо проще)
2. Наличие хорошей документации и Javadoc’ов, которые можно сделать для всех библиотек(не только для системных)
0. А что такое «бот»?
Бот — это профиль в соцсети/мессенджере(в данном случае Telegram) который отвечает на команды.( В любом случае все действия буду происходить после выполнения команды)
Тип чата с ботом — это переписка 1 на 1.
1.С чего же начинать?
Здесь качать библиотеку Telegram(обязательно with-dependiciens)
IDE можно выбрать любую, я бы порекомендовал eclipse.
Импотрируем библиотеку Телеграма и приступаем.
2.Наследование бота
Для того чтобы отвечать на команды, класс должен наследовать TelegramLongPillingBot

package ru.thematdev.bot; import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.bots.TelegramLongPollingBot; public class Example extends TelegramLongPollingBot < public static void main(String[] args) < ApiContextInitializer.init(); // Инициализируем апи TelegramBotsApi botapi = new TelegramBotsApi(); try < botapi.registerBot(new Bot()); >catch (TelegramApiException e) < e.printStackTrace(); >> @Override public String getBotUsername() < return "USER"; //возвращаем юзера >@Override public void onUpdateReceived(Update e) < // Тут будет то, что выполняется при получении сообщения >@Override public String getBotToken() < return "YOUR_BOT_TOKEN"; //Токен бота >>
Получить токен и username можно вбив в поиск @BotFather и написать ему /newbot
3.Как же нам добавить в него что-нибудь?
В телеграме нет «приветствующего сообщения», но когда мы нажимаем кнопку «Start» чтобы начать общение с ботом, то автоматом прописывается команда «/start», поэтому для начала добавим именно её. В telegramapi нету метода отправить сообщение по типу send(строка), но мы его создадим, после всех войдов пишем:
@SuppressWarnings("deprecation") // Означает то, что в новых версиях метод уберут или заменят private void sendMsg(Message msg, String text) < SendMessage s = new SendMessage(); s.setChatId(msg.getChatId()); // Боту может писать не один человек, и поэтому чтобы отправить сообщение, грубо говоря нужно узнать куда его отправлять s.setText(text); try < //Чтобы не крашнулась программа при вылете Exception sendMessage(s); >catch (TelegramApiException e) < e.printStackTrace(); >>
А в UpdateReceived дописываем это:
Message msg = e.getMessage(); // Это нам понадобится String txt = msg.getText(); if (txt.equals("/start"))
4.Ура, всё получилось, как запустить?
Можно в Runnable JAR File так как у нас есть метод main, но лучше запускать прямо из IDE:

Когда мы запустили бота, зарегистрировали и получили токен у BotFather, то мы можем написать ему /start и увидеть что всё работает. Но бот будет работать только когда он запущен.(Много ему не нужно, за 50-100 рублей/месяц на хостинге можно держать). Также с помощью Telegram API можно отправлять картинки, создавать inline-ботов с кнопками и многое другое, но о этом уже в продолжении…
Спасибо всем за просмотр!
Автор: весёлый усач
Создание Telegram-бота на Java: от идеи до деплоя


Что же такое вообще боты? Подробно почитать об этом можно здесь. Для начала вам необходимо ознакомиться с официальной документацией к библиотеке для разработки ботов на Telegram(далее API). Лежит она здесь. Там все очень доступно и понятно. Казалось бы, пиши да радуйся! Но не все так просто. Проведя много времени в поисковиках я находил отрывки знаний по разработке ботов, например, как сделать клавиатуру, обработать CallbackQuery и тому подобное. Полного и исчерпывающего руководства для разработки ботов на Java я так и не нашел. Это и натолкнуло меня на написание этой статьи. В Интернете много сайтов, где можно создать своего бота с уже готовым деплоем. Но дело в том. что в своем большинстве создаются боты, которые могут предоставить справочную информацию и прочее. Наш бот — полноценное веб-приложение, к которому можно привязать базу данных, выполнять запросы на различные API, парсить сайты, выполнять сложные вычисления и прочее. Дело ограничено только вашей фантазией. Я надеюсь что в этих строках я немного разъяснил вам о чем собираюсь писать. Бота в Telegram зарегистрировать очень просто, этот процесс подробно описан в документации по ссылке выше. Для нашего приложение необходимо знать только имя бота и токен, который вы получите при регистрации. По сути бот — просто консольное веб-приложение. Никакого фронтенда, чистая обработка команд. Если вы желаете хорошо освоить Hibernate или научиться парсить JSON, то такой проект для вас. Начнем с того чтобы подключить зависимость в pom.xml (подразумеваем что вы используете Maven). Сделать это можно так:
org.telegram telegrambots 3.5
Затем создаем класс Bot , унаследуем его от класса TelegramLongPollingBot , переопределив его методы:
public class Bot extends TelegramLongPollingBot < /** * Метод для приема сообщений. * @param update Содержит сообщение от пользователя. */ @Override public void onUpdateReceived(Update update) < String message = update.getMessage().getText(); sendMsg(update.getMessage().getChatId().toString(), message); >/** * Метод для настройки сообщения и его отправки. * @param chatId id чата * @param s Строка, которую необходимот отправить в качестве сообщения. */ public synchronized void sendMsg(String chatId, String s) < SendMessage sendMessage = new SendMessage(); sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setText(s); try < sendMessage(sendMessage); >catch (TelegramApiException e) < log.log(Level.SEVERE, "Exception: ", e.toString()); >> /** * Метод возвращает имя бота, указанное при регистрации. * @return имя бота */ @Override public String getBotUsername() < return ”BotName”; >/** * Метод возвращает token бота для связи с сервером Telegram * @return token для бота */ @Override public String getBotToken() < return ”BotToken”; >>
Ну и содержимое метода main :
public static void main(String[] args) < ApiContextInitializer.init(); TelegramBotsApi telegramBotsApi = new TelegramBotsApi(); try < telegramBotsApi.registerBot(Bot.getBot()); >catch (TelegramApiRequestException e) < e.printStackTrace(); >>
Вписав в методы getBotUsername() и getBotToken() мы запускаем бота. Пока он только перенаправляет нам любые сообщения, которые мы отправим ему, этакое «зеркало». Работает это все следующим образом: когда вы запускаете приложение, оно начинает раз в n количество секунд отправлять на сервер Telegram GET запрос по следующему URL: https://api.telegram.org/BotToken/getMe, где BotToken – токен вашего бота, получая в ответ JSON, в котором находятся все сообщения. Каждое такое сообщение обрабатывается библиотекой и приходит в метод OnUpdateReceived(Update update) объектом Update . С ним то мы и работаем. В этом вся прелесть Telegram-ботов, они могут работать на любом компьютере, для тестирования нужно просто запустить приложение, не нужно деплоить его на хостинг после каждого изменения. Это очень удобно. Само собой бота можно настроить на работу по вебхуку, руководство можно найти на просторах Интернета, мы будем для простоты работать по LongPolling. То как обрабатывать сообщения и что отправлять в ответ ограничено только лишь средствами языка и библиотекой, все остальное на ваше усмотрение. Вы можете сделать бота, который будет искать для вас видео на YouTube, можете сделать бота, который каждый день будет присылать вам то, что вы отправите себе, к примеру, за год, эдакую капсулу времени. А можете научиться интегрироваться к CRM-системам и делать ботов для малого бизнеса, все ограничено вашей фантазией. Идем дальше. Те, кто пользовался ботами знают, что с ними удобно взаимодействовать командами, начинающимися со знака «/» , например /start . Но есть способ удобнее — кнопки. Есть два вида кнопок: те, что появляются под полем ввода, ReplyKeyboardMarkup и кнопки, которые находятся непосредственно под сообщением, к которому привязаны, InlineKeyboardMarkup . В документации вы можете поверхностно ознакомиться с их описанием. ReplyKeyboardMarkup. По сути это — массив массивов кнопок, List> . Вот пример кода, который создает клавиатуру
public synchronized void setButtons(SendMessage sendMessage) < // Создаем клавиуатуру ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); sendMessage.setReplyMarkup(replyKeyboardMarkup); replyKeyboardMarkup.setSelective(true); replyKeyboardMarkup.setResizeKeyboard(true); replyKeyboardMarkup.setOneTimeKeyboard(false); // Создаем список строк клавиатуры Listkeyboard = new ArrayList<>(); // Первая строчка клавиатуры KeyboardRow keyboardFirstRow = new KeyboardRow(); // Добавляем кнопки в первую строчку клавиатуры keyboardFirstRow.add(new KeyboardButton(“Привет”)); // Вторая строчка клавиатуры KeyboardRow keyboardSecondRow = new KeyboardRow(); // Добавляем кнопки во вторую строчку клавиатуры keyboardSecondRow.add(new KeyboardButton(“Помощь”); // Добавляем все строчки клавиатуры в список keyboard.add(keyboardFirstRow); keyboard.add(keyboardSecondRow); // и устанваливаем этот список нашей клавиатуре replyKeyboardMarkup.setKeyboard(keyboard); >
В методе sendMsg() мы вызываем этот метод, передавая ему сообщение, таким образом устанавливая для такого сообщения клавиатуру. Когда мы отправим это сообщение пользователю, то он увидит текст сообщения, который мы установили, а также 2 кнопки, на которых будет написано Привет и Помощь, друг под дружкой. По нажатию на эти кнопки боту будет отправлено сообщение, текст которого представляет собой то, что написано на кнопке. То есть если клиент нажмет «Помощь», то боту придет сообщение с текстом “Помощь“. Для него это как будто бы клиент сам написал текст “Помощь“ и отправил бы ему. Ну а затем вы обрабатываете такие сообщения.
InlineKeyboardMarkup Это тоже массив массивов, он похож на предыдущий Markup, но логика работы здесь немного другая. Такая клавиатура привязывается к определенному сообщению и существует только для него. Вот метод для установки Inline-клавиатуры
private void setInline() < List> buttons = new ArrayList<>(); List buttons1 = new ArrayList<>(); buttons1.add(new InlineKeyboardButton().setText(“Кнопка“).setCallbackData(17)); buttons.add(buttons1); InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup(); markupKeyboard.setKeyboard(buttons); >
Создаем List в List , добавляем в первую строку Inline-кнопку. Такая кнопка может содержать URL, ссылку на канал или же CallbackQuery , о которой я напишу чуть позже. Здесь мы устанавливаем текст для нашей кнопки, который будет видеть пользователь, а затем устанавливаем данные, которые будут отправлены боту. В нашем примере пользователь видит «Привет», а боту при нажатии отправится число 17, это и есть наш CallbackQuery . Пару слов о CallbackQuery . Для получения таких данных из объекта Update нужно выполнить update.getCallbackQuery() , этот метод возвращает CallbackQuery , из которого уже можно получить данные, переданные боту. Не нужно пытаться получить эти данные через метод update.getMessage().getText() , получите NullPointerException .
@Override public void onUpdateReceived(Update update) < if(update.hasMessage()) < ThreadClass thread = new ThreadClass(update.getMessage()); >else if(update.hasCallbackQuery()) < AnswerCallbackThread answerThread = new AnswerCallbackThread(update.getCallbackQuery()); >>
Если есть сообщение, отправляем на обработку в новый поток сообщение, если есть CallbackQuery , отправляем его на обработку в соответствующий поток. На CallbackQuery можно отправлять ответ. У каждого объекта в Telegram есть свой id. Для отправки ответа на определенный CallbackQuery нужно знать лишь его id, который мы получим из соответствующего объекта. Для отправки ответа вызовем такой метод:
public synchronized void answerCallbackQuery(String callbackId, String message) < AnswerCallbackQuery answer = new AnswerCallbackQuery(); answer.setCallbackQueryId(callbackId); answer.setText(message); answer.setShowAlert(true); try < answerCallbackQuery(answer); >catch (TelegramApiException e) < e.printStackTrace(); >>
ВАЖНО: Текст в ответе на CallbackQuery должен быть не длиннее 200 символов! При отправке такого ответа клиент получит всплывающее окно, в котором будет написано сообщение. Такое окно может исчезнуть через несколько секунд само после появления, а может висеть до тех пор, пока пользователь не нажмет ок. Для переключения этих режимов мы вызываем метод answer.setShowAlert(true) . При true окошко висит до нажатия ок, при false исчезает через 5 секунд. В принципе это все базовые фишки библиотеки Telegram bot. Такие вещи как отправка мультимедиа, геолокации и тд вы при желании сможете освоить из документации. Давайте перейдем к деплою нашего бота на хостинге. Для своего проекта я выбрал Heroku, тк по моему мнению это достаточно удобный хостинг, который имеет свой CLI. Он бесплатен, но на таком тарифе ваш бот при отсутствии запросов будет уходить в спячку через 30 минут. Когда же к нему будет отправлен запрос, он просыпается. Это происходит довольно быстро, вы даже не заметите(если конечно коннект к БД не поднимается заново). Ограничение на бесплатный тариф — 5MБ база данных, 100МБ дисковое пространство, 2ТБ траффика в месяц, 1 дино. Дино — это ваше запущенное приложение. Скажу сразу, именно стадия деплоя вызвала у меня трудности, так как я до этого никогда не разворачивал свои приложения. Heroku при деплое требует наличия файла с именем Procfile(без расширения). Создаем его в корне проекта, пишем туда worker: sh target/bin/workerBot workerBot – имя, которое мы указываем в pom.xml Будет запускаться sh скрипт, генерируемый с помощью Maven плагина appassembler-maven-plugin. В скрипте описан запуск скомпилированного jar. Имя запускаемого класса указывается между , имя скрипта между pom.xml:
. . org.codehaus.mojo appassembler-maven-plugin 1.1.1 target com.home.server.TelegramBot workerBot package assemble
Перед началом этого процесса вам следует зарегистрироваться на Heroku, установить Git и Heroku CLI. Если вашему приложению необходима БД, то при оформлении нового приложения не забудьте добавить нужную вам БД. Далее вам необходимо узнать host, username, password и port вашей БД, а после указать в своем приложении. Далее перед деплоем выполните сборку вашего проекта с помощью Maven.
mvn clean install
Для начала мы переходим в каталог нашего проекта, инициализируем репозиторий командой git init Затем добавляем в этот репозиторий свой проект
git add .
После коммитим изменения
git commit -m “First commit in project”
Далее вам нужно залогиниться на heroku, пишем в командной строке
heroku login
Вводим свои данные, указаные при регистрации. После вам нужно узнать URL вашего репозитория на heroku, делается это в настройках. Затем пишем
git remote add heroku [url]
Для вашего репозитория добавится удаленный репозиторий heroku. Далее пишем
git push heroku master
Ждем… При успешном деплое приложения выполняем команду
heroku ps:scale worker=1
И все, ваше приложение запущено. Если же этого не произошло, просмотрите внимательно логи, скорее всего возникает ошибка в вашем приложении, из-за которой оно упало. Спасибо за прочтение такой длинной статьи, надеюсь кому-нибудь это окажется полезным и сэкономит массу времени в тех местах, где я спотыкался при разработке.
Telegram-бот счётчик сообщений на Java и Spring Boot
Пишем простой Телеграм-бот на Java, который будет подсчитывать сообщения от пользователей чата и записывать их в БД через PostgreSQL.
В этой статье я покажу, как написать Telegram-бот на Java с использованием Spring Boot, PostgreSQL и JPA. Также создадим исполняемый jar-файл. Сам же бот будет подсчитывать сообщения от пользователей и записывать эти данные в БД.
- Создаём Spring проект на Java
- Реализация базового функционала
- Добавление кнопок
- Подключение Telegram-бота на Java к базе данных
- Создание исполняемого jar-файла в Intellij IDEA
- Выводы
Создаём Spring проект на Java
Для этого воспользуемся сервисом быстрого создания Spring Initializr: он предоставляет интерфейс для генерации заготовки проекта с добавлением стандартных зависимостей. При необходимости в дальнейшем их можно настроить под свои нужды.
Мои настройки Spring Initializr выглядят так:
Обратите внимание на кнопку Add Dependencies: с её помощью можно добавить важные зависимости уже на старте.
После того, как вы всё указали, нажмите Generate, разархивируйте стартовый проект и откройте его с помощью удобной IDE. У меня это IntelliJ IDEA.
Реализация базового функционала
Для начала напишем на Java самый примитивный Telegram bot, который будет отвечать на наши сообщения.
Создание Telegram-бота и конфигурация
Начнём с того, что это Maven-проект. Сразу добавим в pom.xml дополнительные зависимости для работы с Телеграм ботом и базами данных:
- Telegram Bots
- Hibernate Core Relocation
- PostgreSQL JDBC Driver
- Lombok
В каталоге resources создадим файл config.properties , где будут храниться данные для подключения к боту и в будущем к БД.
Примечание Данный файл не следует включать в коммиты.
Теперь создадим бота. Для этого перейдём в Telegram в BotFather и создадим нового бота командой /newbot . Выбираем для него название, которое будет отображаться для всех, и его username. После этого BotFather выдаст токен для взаимодействия с бэкендом Телеграмма.
Теперь запишем в файл config.properties следующее:
bot.name = юзернейм_вашего_бота bot.token = токен_вашего_бота bot.chatId = id_нужного_чата
Добавим в основной каталог проекта пакет config , а внутри него создадим новый класс BotConfig .
Вы наверняка заметили, что мы добавили в pom.xml Lombok. Это популярная библиотека для сокращения кода и расширения функциональности Java. С ней и Spring наш класс BotConfig будет выглядеть очень лаконично:
@Configuration @Data @PropertySource("config.properties") public class BotConfig < @Value("$") String botName; @Value("$") String token; @Value("$") String chatId; >
Что здесь происходит?
- @Configuration указывает, что класс содержит методы определения @Bean (наши @Value ).
- @Data на этапе компиляции генерирует для всех полей геттеры, сеттеры, toString и предопределяет equals и hashCode.
С остальным, думаю, всё понятно.
Класс Телеграм бота на Java
Давайте теперь выйдем из пакета config и создадим в основном пакете проекта класс бота. Поскольку это бот-счётчик, назовём его CounterTelegramBot.
Сразу унаследуемся от TelegramLongPollingBot — класса, который позволяет взаимодействовать с Telegram. И имплементируем методы getBotUsername , getBotToken и onUpdateReceived . Создадим конструктор и добавим две аннотации перед классом: @Component (авто-создание экземпляра) и @Slf4j (для работы с логером).
На старте получаем следующий класс:
@Slf4j @Component public class CounterTelegramBot extends TelegramLongPollingBot < final BotConfig config; public CounterTelegramBot(BotConfig config) < this.config = config; >@Override public String getBotUsername() < return config.getBotName(); >@Override public String getBotToken() < return config.getToken(); >@Override public void onUpdateReceived(@NotNull Update update) <> >
Для начала сделаем так, чтобы на команду /start Telegram-бот что-то нам отвечал и выводил в логи сообщение об успехе. Другие сообщения будут выводить в логи «Unexpected message» :
@Override public void onUpdateReceived(@NotNull Update update) < if(update.hasMessage() && update.getMessage().hasText())< String messageText = update.getMessage().getText(); long chatId = update.getMessage().getChatId(); String memberName = update.getMessage().getFrom().getFirstName(); switch (messageText)< case "/start": startBot(chatId, memberName); break; default: log.info("Unexpected message"); >> > private void startBot(long chatId, String userName) < SendMessage message = new SendMessage(); message.setChatId(chatId); message.setText("Hello, " + userName + "! I'm a Telegram bot."); try < execute(message); log.info("Reply sent"); >catch (TelegramApiException e) < log.error(e.getMessage()); >>
И последним штрихом является инициализация бота. Добавим в пакет config класс Initializer :
@Slf4j @Component public class Initializer < @Autowired CounterTelegramBot bot; @EventListener() public void init() < try < TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); telegramBotsApi.registerBot((LongPollingBot) bot); >catch (TelegramApiException e) < log.error(e.getMessage()); >>
- @Autowired обеспечивает контроль над тем, где и как осуществить автосвязывание (чтобы Spring автоматически подключил бота).
- @EventListener — слушатель, который вешаем на изменение класса.
Запустите и проверьте работу бота.
Примечание Если возникает ошибка Failed to configure a DataSource , измените аннотацию в исполняемом классе на @SpringBootApplication(exclude = ) . Ошибка исчезнет, как только мы добавим информацию для доступа к БД в config.properties .
Добавление кнопок
Чтобы Telegram bot на Java и Spring Boot выглядел по-настоящему серьёзным, давайте добавим ему команду /help и пару кнопок.
Создадим в основной директории проекта пакет components . В него добавим:
1. Интерфейс BotCommands :
public interface BotCommands < ListLIST_OF_COMMANDS = List.of( new BotCommand("/start", "start bot"), new BotCommand("/help", "bot info") ); String HELP_TEXT = "This bot will help to count the number of messages in the chat. " + "The following commands are available to you:\n\n" + "/start - start the bot\n" + "/help - help menu"; >
2. Класс Buttons :
public class Buttons < private static final InlineKeyboardButton START_BUTTON = new InlineKeyboardButton("Start"); private static final InlineKeyboardButton HELP_BUTTON = new InlineKeyboardButton("Help"); public static InlineKeyboardMarkup inlineMarkup() < START_BUTTON.setCallbackData("/start"); HELP_BUTTON.setCallbackData("/help"); ListrowInline = List.of(START_BUTTON, HELP_BUTTON); List rowsInLine = List.of(rowInline); InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); markupInline.setKeyboard(rowsInLine); return markupInline; > >
В классе мы создаём две кнопки, которые будут расположены в одной линии. Одна из них отвечает за команду старта, а вторая — за вызов меню помощи.
Теперь немного улучшим класс CounterTelegramBot :
@Slf4j @Component public class CounterTelegramBot extends TelegramLongPollingBot implements BotCommands < final BotConfig config; public CounterTelegramBot(BotConfig config) < this.config = config; try < this.execute(new SetMyCommands(LIST_OF_COMMANDS, new BotCommandScopeDefault(), null)); >catch (TelegramApiException e) < log.error(e.getMessage()); >> @Override public String getBotUsername() < return config.getBotName(); >@Override public String getBotToken() < return config.getToken(); >@Override public void onUpdateReceived(@NotNull Update update) < long chatId = 0; long userId = 0; //это нам понадобится позже String userName = null; String receivedMessage; //если получено сообщение текстом if(update.hasMessage()) < chatId = update.getMessage().getChatId(); userId = update.getMessage().getFrom().getId(); userName = update.getMessage().getFrom().getFirstName(); if (update.getMessage().hasText()) < receivedMessage = update.getMessage().getText(); botAnswerUtils(receivedMessage, chatId, userName); >//если нажата одна из кнопок бота > else if (update.hasCallbackQuery()) < chatId = update.getCallbackQuery().getMessage().getChatId(); userId = update.getCallbackQuery().getFrom().getId(); userName = update.getCallbackQuery().getFrom().getFirstName(); receivedMessage = update.getCallbackQuery().getData(); botAnswerUtils(receivedMessage, chatId, userName); >> private void botAnswerUtils(String receivedMessage, long chatId, String userName) < switch (receivedMessage)< case "/start": startBot(chatId, userName); break; case "/help": sendHelpText(chatId, HELP_TEXT); break; default: break; >> private void startBot(long chatId, String userName) < SendMessage message = new SendMessage(); message.setChatId(chatId); message.setText("Hi, " + userName + "! I'm a Telegram bot.'"); message.setReplyMarkup(Buttons.inlineMarkup()); try < execute(message); log.info("Reply sent"); >catch (TelegramApiException e) < log.error(e.getMessage()); >> private void sendHelpText(long chatId, String textToSend) < SendMessage message = new SendMessage(); message.setChatId(chatId); message.setText(textToSend); try < execute(message); log.info("Reply sent"); >catch (TelegramApiException e) < log.error(e.getMessage()); >> >
switch вынесли в отдельный метод, добавили обработку команд, в том числе и нажатие кнопок.
Подключение Telegram-бота на Java к базе данных
Перед началом работы установите PostgerSQL, если СУБД ещё не установлена. В случае, если вы работаете с другими СУБД, просто измените настройки доступа в файле config.properties. Для тех же, кто работает с PostgerSQL, config.properties будет выглядеть примерно так:
bot.name = юзернейм_вашего_бота bot.token = токен_вашего_бота bot.chatId = id_нужного_чата #db related settings spring.jpa.database = PostgreSQL spring.jpa.show-sql = false # для автоматического создания/обновления таблицы в бд spring.jpa.hibernate.ddl-auto = update spring.datasource.driverClassName = org.postgresql.Driver # ниже прописываете порт и название бд spring.datasource.url = jdbc:postgresql://localhost:5432/tg # ваши кредлы для доступа к бд spring.datasource.username = postgres spring.datasource.password = root
В директорию проекта добавляем пакет database . В нём следует создать:
@Data @Entity(name = "tg_data") //привязываемся к существующей таблице с готовыми колонками public class User < @Id private long id; //BigInt private String name; //Text private int msg_numb; //Integer >
2. Интерфейс UserRepository :
public interface UserRepository extends CrudRepository
Данный интерфейс нам нужен для удобной работы с CrudRepository — интерфейсом данных Spring для общих операций CRUD. Сюда же вшиваем запрос на апдейт нашей таблицы: добавление +1 сообщения пользователю в случае, если он написал в чат.
В классе CounterTelegramBot объявим новый интерфейс с аннотацией @Autowired , которая говорит Spring, что в это поле нужно инжектнуть бин:
@Autowired private UserRepository userRepository;
Там же создаём метод добавления пользователя в базу данных, если он написал впервые, и просто обновление столбца сообщений, если пользователь уже существует:
private void updateDB(long userId, String userName) < if(userRepository.findById(userId).isEmpty())< User user = new User(); user.setId(userId); user.setName(userName); //сразу добавляем в столбец каунтера 1 сообщение user.setMsg_numb(1); userRepository.save(user); log.info("Added to DB: " + user); >else < userRepository.updateMsgNumberByUserId(userId); >>
Финально обновим метод onUpdateReceived в классе CounterTelegramBot :
@Override public void onUpdateReceived(@NotNull Update update) < long chatId = 0; long userId = 0; String userName = null; String receivedMessage; if(update.hasMessage()) < chatId = update.getMessage().getChatId(); userId = update.getMessage().getFrom().getId(); userName = update.getMessage().getFrom().getFirstName(); if (update.getMessage().hasText()) < receivedMessage = update.getMessage().getText(); botAnswerUtils(receivedMessage, chatId, userName); >> else if (update.hasCallbackQuery()) < chatId = update.getCallbackQuery().getMessage().getChatId(); userId = update.getCallbackQuery().getFrom().getId(); userName = update.getCallbackQuery().getFrom().getFirstName(); receivedMessage = update.getCallbackQuery().getData(); botAnswerUtils(receivedMessage, chatId, userName); >if(chatId == Long.valueOf(config.getChatId())) < updateDB(userId, userName); >>
Примечание Вы можете не делать ограничение по chatId , но тогда следует дополнительно прописать логику для создания отдельной таблицы под каждый чат. В моём случае бот писался под конкретный чат.
Важно Не забудьте предоставить боту права администратора чата.
Создание исполняемого jar-файла в Intellij IDEA
У Telegram API есть одно неприятное ограничение, в соответствии с которым наш бот на Java позволяет достучаться только до сообщений, отправленных за последние 24 часа. Всё, что было отправлено раньше, не учтётся.
Поэтому после вы можете либо создать exe-файл с установкой времени выполнения, либо воспользоваться удалённым сервером. Например, в статье о Telegram-боте на Python мы рассказали, как настроить Docker и задеплоить бота на AWS.
Здесь же я просто покажу, как создать исполняемый jar-файл для ручного запуска. Костыльно, но для периодического подсчёта из конкретного чата подходит, а далее можно масштабировать по своему усмотрению.
Инструкция по созданию jar-файла:
- File – Project Structure – Project Settings – Artifacts – Кликаем по кнопке + – Jar – From modules with dependencies.
- Выбираем главный класс проекта и жмем ОK.
- После этого собираем Jar файл: Build – Build Artifact.
- Это создаст .jar, который при двойном клике запустит JVM, если она установлена в ОС.
На первом же скрине вы можете посмотреть структуру проекта.
Выводы
Создание Telegram-бота на Java возможно благодаря специальному классу TelegramLongPollingBot , а Spring Boot и Lombok сильно упрощают этот процесс.
Но стоит отметить, что тот же бот, написанный на Python или PHP, обойдётся вам в меньшее количество строк кода, да и туториалов по таким Телеграм-ботам значительно больше. А вот в качестве практики Java и небольшого пет-проекта, который можно представить в своём резюме, такая программа вполне подойдёт.
Остались вопросы? Задавайте их в комментариях к этой статье.
