Привет, Хабр!

В процессе работы над проектом мне понадобилось выгрузить telegram-бота на VPS. Я не нашёл источника, в котором были бы собраны все детали этого процесса под мой конкретный случай. Поэтому в этой статье я бы хотел поделиться опытом с теми, кто столкнулся с такой же задачей.

Содержание

  1. VPS - что такое и где искать

  2. Что понадобится

  3. Конфигурация и application.properties

  4. Процесс выгрузки

  5. Заключение

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.

Вход в PuTTY
Вход в PuTTY

Далее входим под нашим юзером в систему и начинаем устанавливать нужные нам пакеты

Для начала обновляемся

$ 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)


  1. shark14
    00.00.0000 00:00

    telegram требует SSL-сертификат

    Это только для вебхуков справедливо. Простеньких ботов проще реализовать через long polling и там это не требуется, их можно хоть локально запускать — думаю, об этом стоит написать.


    1. BlackSCORPION
      00.00.0000 00:00

      И о том что SSL сертификат может быть бесплатным от Let's Encrypt, выпускается в одну команду утилитой certbot, с флагом --nginx создаёт в нем же конфигурацию (с другими тоже дружит) и настроит авто перевыпуск сертификата.

      Nginx в качестве реверс прокси сможет перенаправить запросы с нормального домена на локальный компьютер на запущенный в дебаге бот. Если настроить ssh тунель на сервере и использовать proxyPass в nginx на локальный порт ssh туннеля.


      1. shark14
        00.00.0000 00:00

        Так для полноценного (не самоподписанного) сертификата нужен домен и это, как правило, не бесплатно.


        1. BlackSCORPION
          00.00.0000 00:00

          есть бесплатные домены, LetsEncrypt поддерживает любые валидные домены. При проверке он положит файлик на сервер и проверит что он доступен по указанному домену.

          А вообще домены стоят не дорого, большинство можно купить за 10 долларов в год.


    1. yourpaink1ller Автор
      00.00.0000 00:00

      Внёс уточнение. Однако, в заголовке отчётливо указано, что бот на webhooks. С какой целью кто-то будет использовать эту информацию для long polling?


      1. shark14
        00.00.0000 00:00

        Эта статья — начального уровня и, скорее всего, её прочитает человек, который впервые сталкивается с написанием телеграм-ботов. Откуда он знает про вебхуки и long polling?


  1. aleksandy
    00.00.0000 00:00
    +4

    Зачем на серваке нужен мавен и JDK? Для запуска приложения вполне достаточно JRE. Статья ни о чём.


    1. Dmitry2019
      00.00.0000 00:00
      +2

      В Java17 нет различия между JDK и JRE. Конечно, можно было бы и скомпилировать граалем в нативное приложение, тогда джава вообще не нужна.


    1. yourpaink1ller Автор
      00.00.0000 00:00

      Также для создания исполняемого .jar файла на своей машине мне понадобился Maven для терминала

      На нашем устройстве идём в директорию проекта. Тут нам нужно создать исполняемый .jar файл (для этого нужно установить Maven).

      Насчёт JDK согласен, конкретно здесь он лишний. Исправил.

      Есть ли ещё причины, почему статья "ни о чём", или установка лишнего пакета ставит на ней крест?


      1. aleksandy
        00.00.0000 00:00
        +1

        Есть ли ещё причины, почему статья "ни о чём"

        Низкий технический уровень материала. Достаточное основание?


  1. 0lehandro
    00.00.0000 00:00
    +5

    Вероятно, такие вещи надо запускать не прибегая к screen, а как сервис. Иначе при каждом ребуте, или, не дай бог, падении, придется каждый раз перезапускать его вручную?


  1. prilichny
    00.00.0000 00:00
    -2

    да, было бы полезно рассказать про отслеживание падений/перезапуск (ну или как этого избежать)

    не сразу понял, что бот будет на джаве, а не на питоне (который, как будто, самый популярный выбор)