Чтобы запустить бота TelegramBots (Java) 24/7, вы запускаете его на машине, которая всегда включена: на Linux VPS со службой systemd, которая снова поднимает его после остановки, или на тарифе для ботов в хостинге Telegram-ботов PlayNHost (от US$1.99 в месяц), где вы загружаете один исполняемый jar, вставляете токен от @BotFather и нажимаете Start. В нашем тесте бот на TelegramBots 10.3.0, Java-библиотеке от rubenlagus, занял около 91 МБ памяти на Java 21 и получил ответ Telegram через 1,5 секунды после запуска. Используйте её модуль long polling: у наших тарифов пока нет публичного HTTPS-адреса для вебхука. Шаги на PlayNHost:
- На странице Хостинг Telegram-ботов нажмите Создать сервер у тарифа. В окне заказа ответьте на Для какой платформы ваш бот? вариантом Telegram и выберите Java.
- На своём компьютере соберите бота с
pom.xmlниже:mvn packageсоздаётtarget/bot.jarс TelegramBots внутри. - Откройте свой сервер в панели. Карточка Настройка бота на странице Обзор открывается на шаге Подключение к Telegram; его первый шаг, Что запускается, должен показывать Этот бот запускает Java Bot.
- В разделе Подключение к Telegram вставьте токен в поле Вставьте токен бота, нажмите Подключение, проверьте показанное имя бота и нажмите Да, продолжить.
- В разделе Ваш код нажмите Загрузить файлы и загрузите
bot.jarв главную папку. - На странице Бот, в панели Код, проверьте, что Файл запуска равен
bot.jar, а Среда выполнения равна Java 21 (recommended), либо Java 17 или 25. Если вы меняете Файл запуска, нажмите рядом Сохранить; новая Среда выполнения сохраняется сразу после выбора. - Нажмите Запустить бота и откройте Console. Когда ваш бот выведет
Logged in as @your_bot, индикатор на странице Обзор сменится на Онлайн в Telegram. - На странице Бот, в панели Telegram, нажмите Открыть в Telegram и отправьте боту
/start.
Создание бота в @BotFather и шаги в панели описаны в статье Как запустить Telegram-бота на хостинге. Эта страница посвящена самой TelegramBots: что она потребляет на сервере и что стоит знать перед запуском.
Что мы измерили
| Библиотека | Версия | Память без нагрузки | От запуска до ответа Telegram | Размер jar |
|---|---|---|---|---|
| TelegramBots (rubenlagus) | 10.3.0 | 91 МБ | 1,5 с | 9,6 МБ |
| Только Java 21, без библиотеки | 21.0.12.1 | 38 МБ | нет | 0,0 МБ |
Как мы измеряли: на нашей собственной ноде, в одноразовом контейнере, настроенном как тариф для ботов на 1 ГБ (образ Java 21 и точная команда java нашего типа бота Java), бот вызвал getMe у Telegram с поддельным токеном, который Telegram отклонил; память это резидентная память через 15 секунд после этого ответа, время старта считается от запуска до ответа, а каждое значение это медиана запусков со 2-го по 4-й.
Это нижние границы: пока без чатов, без данных и без polling. К ним добавляются ваш собственный код, то, что он держит в памяти, и число чатов, а стартовый скрипт позволяет куче Java расти до 80 процентов тарифа (см. ниже). Сравните цифры с тарифами в хостинге Telegram-ботов и выбирайте по тому, что делает ваш бот.
Минимальный бот на TelegramBots
Он отвечает на /start, читает токен из TELEGRAM_BOT_TOKEN (панель передаёт его вашему коду под этим именем, а также как BOT_TOKEN, TOKEN, TELEGRAM_TOKEN и TELOXIDE_TOKEN) и выводит строку готовности. Два файла:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>bot</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-longpolling</artifactId>
<version>10.3.0</version>
</dependency>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-client</artifactId>
<version>10.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.12</version>
</dependency>
</dependencies>
<build>
<finalName>bot</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.7.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>Bot</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/java/Bot.java
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
import org.telegram.telegrambots.longpolling.util.DefaultLongPollingUpdateConsumer;
import org.telegram.telegrambots.meta.api.methods.GetMe;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.generics.TelegramClient;
public class Bot extends DefaultLongPollingUpdateConsumer {
private final TelegramClient client;
Bot(TelegramClient client) {
this.client = client;
}
@Override
public void consume(Update update) {
if (update.hasMessage() && update.getMessage().hasText()
&& update.getMessage().getText().startsWith("/start")) {
SendMessage reply = SendMessage.builder()
.chatId(update.getMessage().getChatId())
.text("Hello! I am running on PlayNHost.")
.build();
try {
client.execute(reply);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
String token = System.getenv("TELEGRAM_BOT_TOKEN");
if (token == null || token.isBlank()) {
System.out.println("No TELEGRAM_BOT_TOKEN found. Paste your bot token on the Bot page, then restart.");
System.exit(1);
}
TelegramClient client = new OkHttpTelegramClient(token);
User me = null;
try {
me = client.execute(new GetMe());
} catch (TelegramApiRequestException e) {
if (e.getErrorCode() != null && e.getErrorCode() == 401) {
System.out.println("Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart.");
System.exit(1);
}
throw e;
}
try (TelegramBotsLongPollingApplication app = new TelegramBotsLongPollingApplication()) {
// Long polling: registerBot removes a webhook left on the bot, then asks Telegram for messages.
app.registerBot(token, new Bot(client));
System.out.println("Logged in as @" + me.getUserName());
Thread.currentThread().join();
}
}
}
Соберите его с Maven 3.9 и JDK 17 или новее и проверьте jar на своём компьютере:
mvn package
java -jar target/bot.jar
Без токена он выводит No TELEGRAM_BOT_TOKEN found. и останавливается, что доказывает: jar запускается и находит свой главный класс. Загрузите target/bot.jar. Остановите любую копию, запущенную на вашем компьютере с настоящим токеном, прежде чем запускать копию на сервере, иначе обе копии будут получать от Telegram ошибки 409 Conflict.
Вызов getMe проверяет токен до начала polling и возвращает имя пользователя бота для строки готовности. Logged in as @your_bot это строка, после которой индикатор меняется на Онлайн в Telegram.
Если токен неверный
В нашем тесте, с поддельным токеном, вызов getMe в TelegramBots завершился такой ошибкой:
TelegramApiRequestException: Error executing org.telegram.telegrambots.meta.api.methods.GetMe query: [401] Unauthorized
Бот выше перехватывает этот отказ (код ошибки 401) и вместо этого выводит Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart. Панель читает эту строку и показывает над Console баннер Telegram не принял токен вашего бота. Чтобы исправить, отправьте в @BotFather команду /mybots, выберите бота, затем API Token и скопируйте токен заново. На странице Бот, в панели Telegram, нажмите Заменить токен, вставьте его, нажмите Сохранить токен, затем Перезапустить сейчас.
Что стоит знать о TelegramBots на сервере
- Версии: TelegramBots 10.3.0 вышла 7 сент. 2026 и поддерживает Bot API 10.3 от Telegram. Ей нужна Java 17 или новее, поэтому её запускает любая Среда выполнения, которую предлагает панель (Java 17, 21 или 25).
- Два пакета, в отличие от старых руководств. С версии 7.0.0 (март 2024) библиотека состоит из
telegrambots-longpolling, который принимает сообщения, иtelegrambots-client, который их отправляет. Руководства, расширяющиеTelegramLongPollingBot, написаны для старого пакетаtelegrambots, последний раз выпущенного как 6.9.7.1; этого класса нет в 10.3.0, поэтому их код с ней не компилируется. - Используйте long polling. В библиотеке есть и модуль вебхуков, но вебхуку нужен публичный HTTPS-адрес, которого в наших тарифах пока нет.
registerBotв модуле long polling вызываетdeleteWebhookперед стартом, поэтому вебхук, оставшийся от прежнего хоста, удаляется, а ожидающие сообщения сохраняются. Переезд с хоста с вебхуком: Как перенести Telegram-бота на PlayNHost. - Добавьте библиотеку логирования, иначе библиотека молчит. TelegramBots пишет логи через SLF4J. Если в вашем jar нет провайдера SLF4J, SLF4J один раз выводит предупреждение, а затем отбрасывает каждую строку лога библиотеки, включая ошибки polling.
pom.xmlвыше добавляетslf4j-simple, который пишет строки библиотеки уровня INFO и выше в стандартный поток ошибок, так что они видны в Console. - Ошибки polling повторяются, а не выбрасываются. Когда вызов
getUpdatesзавершается ошибкой, TelegramBots пишетError received from Telegram GetUpdates Request, retrying in ... millisи пробует снова, поэтому процесс продолжает работать. Ожидание начинается примерно с полсекунды и каждый раз растёт наполовину до примерно минуты (со случайным разбросом, до 90 секунд); когда проходит 15 минут без успешного вызова, она ждёт 15 минут между попытками. Поэтому после устранения причины перезапустите бота, а не ждите. Что пошло не так, говорит только код состояния HTTP в строкеCaused byтрассировки стека под ней; собственное описание ошибки от Telegram не выводится. Так какregisterBotуже удалил вебхук, 409 здесь скорее всего означает, что другая копия бота ведёт polling с тем же токеном: остановите её. См. Как исправить ошибку 409 Conflict у Telegram-бота. - Официальный урок, обновлённый: в нём реализован
LongPollingSingleThreadUpdateConsumer, который версия 10.3.0 помечает устаревшим в пользу классаDefaultLongPollingUpdateConsumer, использованного выше; оба обрабатывают обновления по одному в фоновом потоке. Его строка готовностиMyAmazingBot successfully started!не переключает индикатор на Онлайн в Telegram: выведите строку, начинающуюся сLogged in as, как выше. - Не давайте
main()завершиться. Polling работает в собственных потоках библиотеки; урок заканчиваетmain()вызовомThread.currentThread().join(), чтобы программа не завершилась, и бот выше делает то же самое. - Лимит памяти: стартовый скрипт запускает Java с
-XX:MaxRAMPercentage=80.0и сборщиком мусора G1, поэтому куча может занимать до 80 процентов памяти тарифа. Если она заполнится, Java выведетjava.lang.OutOfMemoryError, а панель покажет Вашему боту не хватило памяти. - Один jar, на сервере ничего не устанавливается. Тип бота Java запускает
java -jarдля вашего Файл запуска и не имеет поля Пакеты, поэтому всё должно быть внутри jar. Чтобы обновить бота, загрузите новый jar.
Запуск на собственном Linux VPS
VPS нужна только среда Java, потому что jar вы собираете на своём компьютере. На Debian 13 или Ubuntu 24.04 установите Java 21; в Debian 12 есть Java 17, которая тоже запускает jar выше:
sudo apt update
sudo apt install openjdk-21-jre-headless
java -version
Создайте пользователя для бота и скопируйте jar на сервер (например, через scp), затем в его папку:
sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp bot.jar /opt/mybot/
sudo chown -R mybot: /opt/mybot
Держите токен вне кода, в файле, который может читать только root:
sudo sh -c 'echo "TELEGRAM_BOT_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env
Создайте /etc/systemd/system/mybot.service:
[Unit]
Description=TelegramBots Telegram bot
Wants=network-online.target
After=network-online.target
[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/usr/bin/java -XX:MaxRAMPercentage=80.0 -jar /opt/mybot/bot.jar
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Запустите его сейчас и при каждой загрузке, затем следите за его выводом:
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo journalctl -u mybot -f
Restart=always снова запускает бота через 5 секунд после его завершения или сбоя, но не после того, как вы остановили его командой systemctl stop. На VPS -XX:MaxRAMPercentage это доля памяти всей машины, поэтому уменьшите её, если там работают и другие программы. Чтобы обновить бота, скопируйте новый jar поверх старого и выполните sudo systemctl restart mybot.
Свой сервер или тариф для ботов
На VPS, которым вы управляете сами, вам приходится заниматься:
- Обновлениями и безопасностью операционной системы и обновлениями Java.
- Копированием каждого нового jar, файлом службы, файлом токена и его правами.
- Чтением
journalctl, чтобы понять, почему бот остановился или перестал отвечать. - Резервными копиями всего, что хранит ваш бот.
Взамен VPS запускает что угодно, и вы можете дать ему домен с HTTPS для вебхука.
На тарифе для ботов PlayNHost это делает панель:
- Java 17, 21 или 25 на выбор из списка, с уже заданными лимитом кучи и сборщиком мусора.
- Токен, проверенный в Telegram перед сохранением, хранящийся в зашифрованном виде и передаваемый вашему коду под пятью именами.
- Перезапуск бота после сбоя. Если он снова падает в течение минуты, он остаётся остановленным, а Console объясняет причину.
- Кнопка Удалить вебхук в панели Telegram и баннеры над Console, называющие причину, например отклонённый токен или нехватку памяти.
- Загрузка из браузера и резервные копии из панели.
Частые вопросы
Мой бот на TelegramBots работает, но ничего не отвечает и ничего не выводит. Почему?
Чаще всего в jar нет провайдера SLF4J, поэтому собственные строки ошибок библиотеки отбрасываются, пока она продолжает повторять попытки. Добавьте slf4j-simple, как в pom.xml выше, соберите заново и посмотрите Console. Повторяющийся 409 означает, что другая копия бота ведёт polling с тем же токеном; повторяющийся 401 означает, что токен отозван в @BotFather. После исправления перезапустите бота: ожидание TelegramBots между попытками может достигать 15 минут.
Можно ли использовать модуль вебхуков TelegramBots?
На наших тарифах пока нет: вебхуку нужен публичный HTTPS-адрес, которого в них нет. Long polling он не нужен, потому что бот сам запрашивает у Telegram новые сообщения. Используйте telegrambots-longpolling, как на этой странице.
Нужен ли TelegramBots более крупный тариф, чем бот на Python или Node.js?
Не из-за самой библиотеки. В том же тесте, запущенном так же, TelegramBots занял 91 МБ, python-telegram-bot 22.8 занял 44 МБ, grammY 1.46.0 занял 60 МБ, а aiogram 3.31.0 занял 173 МБ, всё это заметно меньше 0,5 ГБ самого маленького тарифа. Остальное решает то, что ваш бот держит в памяти. В Java память зависит ещё и от кучи: стартовый скрипт позволяет ей расти до 80 процентов тарифа, а сборщик мусора решает, сколько из этого она займёт.
Какую версию Java выбрать?
Java 21, рекомендуемую, если вашему коду не нужна 25. TelegramBots 10.3.0 нужна Java 17 или новее. Собирайте с release не новее выбранной Среда выполнения: jar, собранный для более новой Java, останавливается с UnsupportedClassVersionError.
Готовы запустить своего бота на TelegramBots круглосуточно? Посмотрите тарифы в хостинге Telegram-ботов.



