Привет, Хабр!
В процессе работы над проектом мне понадобилось выгрузить telegram-бота на VPS. Я не нашёл источника, в котором были бы собраны все детали этого процесса под мой конкретный случай. Поэтому в этой статье я бы хотел поделиться опытом с теми, кто столкнулся с такой же задачей.
Содержание
1. VPS - что такое и где искать
VPS (virtual private server) или VDS (virtual dedicated server), виртуальный выделенный сервер — услуга предоставления серверных мощностей провайдером.
Существует множество сервисов по подбору VPS с конкретными характеристиками, вот топ-5 популярных провайдеров (взято из этой статьи). Сам я использовал сервис timeweb.
2. Что понадобится
Для начала, сам выделенный сервер, а также домен. В данной статье я буду использовать VPS на Ubuntu 22.04. Важно отметить, что для ботов на webhooks telegram требует SSL-сертификат. Для собственных целей я приобрёл его, однако если вы не хотите тратиться, вы можете использовать self-signed certificate.
Затем для общения с ним нам нужен клиент удалённого доступа. Я использовал PuTTY
Чтобы передать на сервер файлы нашего бота, потребуется FTP-клиент. Мой выбор пал на FileZilla
Также для создания исполняемого
.jar
файла на своей машине мне понадобился Maven для терминала
Установка Maven
Обновляем списки пакетов из репозиториев
$ sudo apt update
Устанавливаем maven
$ sudo apt install maven
Проверяем результат
$ mvn -version
3. Конфигурация и application.properties
Конфигурация моего Spring Boot приложения состоит из трёх файлов: конфигурация Spring, самого бота и файла application.properties
application.properties
telegram.bot-name=[имя вашего бота]
telegram.bot-token=[токен, который можно взять у BotFather]
telegram.webhook-path=[ваш домен в формате https://{вашДомен}:{порт}/bot{токенБота}]
server.port=[порт подключения]
На данном этапе нужно отметить, что telegram поддерживает порты 443, 80, 88 и 8443.
BotConfig.java
import lombok.Getter;
/* lombok - это плагин компилятора, который добавляет в Java
новые «ключевые слова» и превращает аннотации в Java-код,
уменьшая усилия на разработку и обеспечивая некоторую
дополнительную функциональность. */
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration // помечаем класс, как конфигурацию
@Getter // устанавливаем геттеры каждому полю класса
public class BotConfig {
/* с помощью @Value получаем значения из файла application.properties
и устанавливаем их в соответствующие поля*/
@Value("${telegram.bot-name}")
String botName;
@Value("${telegram.bot-token}")
String token;
@Value("${telegram.webhook-path}")
String webhookPath;
}
SpringConfig.java
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import something.MessageHandler;
import something.MyBot;
@Configuration
@AllArgsConstructor // вносим конструктор для всех параметров
public class SpringConfig {
private final BotConfig telegramConfig;
@Bean
public SetWebhook setWebhookInstance() {
return SetWebhook.builder()
.url(telegramConfig.getWebhookPath()).build();
}
@Bean
public MyBot springWebhookBot(SetWebhook setWebhook,
MessageHandler messageHandler) {
MyBot bot = new MyBot(setWebhook, messageHandler);
bot.setBotPath(telegramConfig.getWebhookPath());
bot.setBotUsername(telegramConfig.getBotName());
bot.setBotToken(telegramConfig.getToken());
return bot;
}
}
4. Процесс выгрузки
Настраиваем окружение
Открываем PuTTY и подключаемся к нашему серверу. Все требуемые данные для входа должен предоставить провайдер после аренды VPS.
Вводим (1) IP в графу Host Name и жмём (2) Open.
Далее входим под нашим юзером в систему и начинаем устанавливать нужные нам пакеты
Для начала обновляемся
$ sudo apt update
Устанавливаем нужный пакет JRE (Java Runtime Environment)
. Я использую 17-ю версию Java, поэтому пишу следующую команду
$ apt install openjdk-17-jre-headless
Также нам потребуется утилита screen - консольная утилита позволяющая в действующей SSH сессии открывать неограниченное количество независимых виртуальных терминалов. Это нужно для того, чтобы после завершения удалённого подключения наш бот не решил, что отношения на расстоянии это не для него продолжал свою работу. Она может быть установлена по дефолту, однако если это не так:
$ apt install screen
Все нужные команды для работы с этой утилитой можно найти здесь.
Последние штрихи и перенос на сервер
На нашем устройстве идём в директорию проекта. Тут нам нужно создать исполняемый .jar
файл (для этого нужно установить Maven). Пишем следующее:
$ maven clean install
После этого в папке botDirectory/target должны появиться два файла: BOTNAME-0.0.1-SNAPSHOT.jar
и BOTNAME-0.0.1-SNAPSHOT.jar.original
Переходим в FileZilla. Вводим IP, имя пользователя, пароль, порт 22 и нажимаем Quickconnect. Теперь полностью переносим директорию с приложением в root, чтобы получилось вот так:
Передаём адрес telegram'y
Далее нужно сообщить телеграму, что наш бот будет работать через Webhook. Для этого в адресной строке вводим запрос:
https://api.telegram.org/bot{ТокенБота}/setWebhook?url={АдресСвоегоWebhook}
Запускаем бота на сервере
Заходим в PuTTY и выполняем такую команду. Она создаст для нас тот самый screen, который будет поддерживать работу нашего приложения после нашего выхода.
$ sudo screen -S bot
Затем в этом скрине переходим в директорию botDirectory/target и вводим следующее:
$ java -jar BOTNAME-0.0.1-SNAPSHOT.jar
В случае успеха увидим следующую картину. После можем закрыть наш screen сочетанием Ctrl+A+D и выйти из клиента.
Заключение
Надеюсь, что статья получилась наглядной и не скомканной. Старался продемонстрировать процесс последовательно и предоставить все нужные ссылки. Получилось же у меня или нет, вы можете сообщить в комментариях. Это моя первая тех. статья, поэтому с удовольствием приму любую критику и замечания. Всем мир!
Комментарии (12)
aleksandy
00.00.0000 00:00+4Зачем на серваке нужен мавен и JDK? Для запуска приложения вполне достаточно JRE. Статья ни о чём.
Dmitry2019
00.00.0000 00:00+2В Java17 нет различия между JDK и JRE. Конечно, можно было бы и скомпилировать граалем в нативное приложение, тогда джава вообще не нужна.
yourpaink1ller Автор
00.00.0000 00:00Также для создания исполняемого
.jar
файла на своей машине мне понадобился Maven для терминалаНа нашем устройстве идём в директорию проекта. Тут нам нужно создать исполняемый
.jar
файл (для этого нужно установить Maven).Насчёт JDK согласен, конкретно здесь он лишний. Исправил.
Есть ли ещё причины, почему статья "ни о чём", или установка лишнего пакета ставит на ней крест?
aleksandy
00.00.0000 00:00+1Есть ли ещё причины, почему статья "ни о чём"
Низкий технический уровень материала. Достаточное основание?
0lehandro
00.00.0000 00:00+5Вероятно, такие вещи надо запускать не прибегая к screen, а как сервис. Иначе при каждом ребуте, или, не дай бог, падении, придется каждый раз перезапускать его вручную?
prilichny
00.00.0000 00:00-2да, было бы полезно рассказать про отслеживание падений/перезапуск (ну или как этого избежать)
не сразу понял, что бот будет на джаве, а не на питоне (который, как будто, самый популярный выбор)
shark14
Это только для вебхуков справедливо. Простеньких ботов проще реализовать через long polling и там это не требуется, их можно хоть локально запускать — думаю, об этом стоит написать.
BlackSCORPION
И о том что SSL сертификат может быть бесплатным от Let's Encrypt, выпускается в одну команду утилитой certbot, с флагом --nginx создаёт в нем же конфигурацию (с другими тоже дружит) и настроит авто перевыпуск сертификата.
Nginx в качестве реверс прокси сможет перенаправить запросы с нормального домена на локальный компьютер на запущенный в дебаге бот. Если настроить ssh тунель на сервере и использовать proxyPass в nginx на локальный порт ssh туннеля.
shark14
Так для полноценного (не самоподписанного) сертификата нужен домен и это, как правило, не бесплатно.
BlackSCORPION
есть бесплатные домены, LetsEncrypt поддерживает любые валидные домены. При проверке он положит файлик на сервер и проверит что он доступен по указанному домену.
А вообще домены стоят не дорого, большинство можно купить за 10 долларов в год.
yourpaink1ller Автор
Внёс уточнение. Однако, в заголовке отчётливо указано, что бот на webhooks. С какой целью кто-то будет использовать эту информацию для long polling?
shark14
Эта статья — начального уровня и, скорее всего, её прочитает человек, который впервые сталкивается с написанием телеграм-ботов. Откуда он знает про вебхуки и long polling?