НОВОЕ 📢 Ограниченное стартовое предложение: скидка до 70% на первый месяц для любой игры!Посмотреть тарифы

Как запустить бота teloxide 24/7

Хостинг Telegram-ботовUpdated Nov 6, 202612 min read

Чтобы запустить бота teloxide 24/7, его нужно держать на машине, которая всегда включена: на Linux VPS со службой systemd, которая запускает бота снова после остановки, или на тарифе для ботов в PlayNHost (от US$1.99 в месяц), где вы загружаете готовую программу, а панель передаёт ей токен и запускает её снова, если она упала. В нашем тесте бот на teloxide 0.17.0 занял около 13 МБ памяти. Бот на Rust собирается на вашем компьютере как одна программа для Linux x86-64: на сервере ничего не компилируется. Bot::from_env() из teloxide читает токен из TELOXIDE_TOKEN, имени, которое панель задаёт за вас. Шаги в PlayNHost:

  1. Соберите бота под Linux x86-64 на своём компьютере, как показано ниже в разделе Сборка под Linux.
  2. На странице хостинга Telegram-ботов нажмите Создать сервер на выбранном тарифе. В окне заказа на вопрос Для какой платформы ваш бот? ответьте Telegram и выберите Rust.
  3. Откройте сервер в панели. Карточка Настройка бота на странице Обзор открывается на шаге Подключение к Telegram; его первый шаг, Что запускается, должен показывать Этот бот запускает Rust Bot.
  4. На шаге Подключение к Telegram вставьте токен от @BotFather в поле Вставьте токен бота, нажмите Подключение, проверьте показанное имя бота и нажмите Да, продолжить.
  5. На шаге Ваш код нажмите Загрузить файлы, затем в разделе Files нажмите Загрузить и выберите свою программу с именем bot. Или пусть сервер скачает её сам: на странице Бот, во вкладке Код, в карточке Настройки, укажите в поле Ссылка для скачивания (необязательно) https-ссылку на программу и нажмите Сохранить.
  6. Нажмите Запустить бота и откройте Console. После [PlayNHost] Starting your bot бот выводит Logged in as @your_bot, а индикатор на странице Обзор меняется на Онлайн в Telegram.
  7. На странице Бот, во вкладке Telegram, нажмите Открыть в Telegram и отправьте боту /start.

Создание бота в @BotFather и карточка настройки описаны в статье Как запустить Telegram-бота на хостинге. Сам тип Rust Bot (Файл запуска, Аргументы запуска (необязательно) и ссылка для скачивания) одинаков для ботов Discord и Telegram: Как запустить Discord-бота на Rust. Эта страница посвящена teloxide: что он использует на сервере и что стоит знать, прежде чем его запускать.

Что мы измерили

БиблиотекаВерсияПамять без нагрузкиСтарт до ответа платформыРазмер программы
teloxide (Telegram)0.17.013 МБ0.1 с3.0 МБ
serenity (Discord)0.12.510 МБ0.4 с13.4 МБ

Как мы измеряли: на нашем собственном узле, в одноразовом контейнере, настроенном как тариф для ботов на 1 ГБ с одним CPU, с образом Debian, на котором работает наш тип Rust Bot, каждая программа обращалась к Telegram или Discord с поддельным токеном, который был отклонён. Память это резидентная память через 15 секунд после этого ответа, время старта считается от запуска до ответа, а каждое значение это медиана запусков с 2 по 4. Обе программы собраны стабильным Rust и cargo build --release на том же образе, с добавленными для сборки pkg-config и libssl-dev; сборка teloxide заняла 107 с на одном CPU, включая загрузки, так что считайте это приблизительной цифрой.

Это нижние границы: программа без чатов и без данных. Ваш собственный код, то, что он хранит в памяти, и число чатов прибавляются к ним, поэтому минимальная программа на teloxide занимает небольшую часть тарифа STARTER на 0.5 ГБ.

Минимальный бот на teloxide

Он отвечает на /start, читает токен, который даёт панель, выводит строку о готовности и прямо сообщает, когда Telegram отклоняет токен. Создайте проект командой cargo new bot и используйте эти два файла. Имя пакета bot даёт программу bot, то есть стандартный Файл запуска.

Cargo.toml

[package]
name = "bot"
version = "0.1.0"
edition = "2021"

[dependencies]
teloxide = { version = "0.17", features = ["macros"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
pretty_env_logger = "0.5"

src/main.rs

use teloxide::{prelude::*, utils::command::BotCommands, ApiError, RequestError};

#[derive(BotCommands, Clone)]
#[command(rename_rule = "lowercase")]
enum Command {
    /// Say hello.
    Start,
}

async fn answer(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
    match cmd {
        Command::Start => {
            bot.send_message(msg.chat.id, "Hello! I am running on PlayNHost.").await?;
        }
    }
    Ok(())
}

#[tokio::main]
async fn main() {
    // Prints teloxide's errors, such as a 409 Conflict while polling. Without a logger they are silent.
    pretty_env_logger::init();

    // Reads TELOXIDE_TOKEN, which the panel sets from the token on the Telegram pane.
    let bot = Bot::from_env();

    match bot.get_me().await {
        Ok(me) => println!("Logged in as @{}", me.username()),
        Err(RequestError::Api(ApiError::InvalidToken)) => {
            println!("Telegram did not accept the bot token. Paste the current one from @BotFather, then restart.");
            std::process::exit(1);
        }
        Err(err) => {
            println!("Could not start the bot: {err}");
            std::process::exit(1);
        }
    }

    // Long polling: removes a webhook left on the bot, then asks Telegram for messages.
    Command::repl(bot, answer).await;
}

Строка Logged in as @your_bot переключает индикатор на Онлайн в Telegram. Command::repl работает, пока бот не остановлен. Код следует примеру команды из репозитория самого teloxide; pretty_env_logger это логгер, который используют примеры teloxide.

Сборка под Linux

Сервер запускает вашу программу на Debian 13, с glibc 2.41 и OpenSSL 3. Файл .exe для Windows или сборка для macOS там не запустятся: консоль тогда пишет [PlayNHost] bot is not a Linux program. Build it for Linux x86-64 (not Windows or macOS) and upload it again. Есть два способа сборки:

В Linux, со стандартными функциями teloxide

sudo apt install build-essential pkg-config libssl-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo build --release

Программа лежит в target/release/bot. Стандартные функции teloxide используют native-tls, который в Linux подключает системный OpenSSL, поэтому для сборки нужны pkg-config и libssl-dev; на сервере есть OpenSSL 3. Собирайте на Debian 12 или 13, либо Ubuntu 22.04 или 24.04: их glibc (2.36, 2.41, 2.35 и 2.39) не новее серверной. Программа, собранная в более новой системе, например в Ubuntu 26.04 с glibc 2.43, может запросить функции, которых нет на сервере, и тогда при старте остановится с ошибкой, что версия GLIBC_ не найдена. Сборка с musl этого избегает.

Из Windows, macOS или любого Linux: сборка с musl

Программа musl состоит из одного самодостаточного файла и не зависит от системных библиотек сервера. Переключите teloxide с OpenSSL на rustls, которому OpenSSL не нужен и который несёт собственный список доверенных сертификатов. В Cargo.toml замените строку teloxide на:

teloxide = { version = "0.17", default-features = false, features = ["macros", "ctrlc_handler", "rustls"] }

Оставьте ctrlc_handler в списке: teloxide собирает repl только с этой функцией. Затем соберите с помощью cargo-zigbuild, который использует Zig как компоновщик (установка через pip ставит и Zig):

rustup target add x86_64-unknown-linux-musl
pip install cargo-zigbuild
cargo zigbuild --release --target x86_64-unknown-linux-musl

Программа окажется в target/x86_64-unknown-linux-musl/release/bot. Для teloxide 0.17 минимальная версия Rust указана 1.82, а используемые им крейты могут потребовать более новую, поэтому перед сборкой выполните rustup update stable.

Если токен неверный

В нашем тесте с поддельным токеном bot.get_me() вернул такую ошибку (наша тестовая программа вывела её после типа ошибки):

teloxide::RequestError: A Telegram's error: Invalid bot token

teloxide превращает ответ Telegram Unauthorized и ответ Not Found, который получает неправильно составленный токен, в ApiError::InvalidToken. Бот выше проверяет это до начала поллинга, выводит Telegram did not accept the bot token. Paste the current one from @BotFather, then restart. и останавливается. Без этой проверки Command::repl завершает программу паникой, Couldn't prepare dispatching context: Api(InvalidToken). Панель распознаёт оба случая и показывает над Console баннер Telegram не принял токен вашего бота.

Чтобы это исправить, отправьте в @BotFather команду /mybots, выберите своего бота, затем API Token и снова скопируйте токен. На странице Бот, во вкладке Telegram, нажмите Заменить токен, вставьте его, нажмите Сохранить токен, затем Перезапустить сейчас.

Что нужно знать о teloxide на сервере

  • Имя токена. Bot::from_env() читает TELOXIDE_TOKEN и паникует с сообщением Cannot get the TELOXIDE_TOKEN env variable, если токена нет. Панель задаёт его, как только токен сохранён во вкладке Telegram, вместе с TELEGRAM_BOT_TOKEN, BOT_TOKEN, TOKEN и TELEGRAM_TOKEN. from_env() также читает TELOXIDE_API_URL и TELOXIDE_PROXY, если они заданы; не задавайте их, чтобы обращаться к Telegram напрямую.
  • Нет логгера, нет ошибок. teloxide сообщает о проблемах через крейт log, поэтому программа без логгера ничего не выводит, когда поллинг даёт сбой. pretty_env_logger::init() показывает только ошибки, и этого достаточно: когда другая копия бота опрашивает Telegram с тем же токеном, в консоли появляется строка, заканчивающаяся на An error from the update listener: Api(TerminatedByOtherGetUpdates), а панель показывает Ваш бот работает ещё и в другом месте. Для более подробных логов на странице Бот, во вкладке Окружение, добавьте переменную RUST_LOG со значением info (Добавить переменную) и перезапустите.
  • Поллинг никогда не сдаётся. Когда запрос сообщений у Telegram не удаётся, teloxide ждёт и пробует снова, удваивая ожидание от 1 секунды до 64 секунд, или столько, сколько попросит Telegram после 429 Too Many Requests. Вторая копия бота или токен, отозванный во время работы, не останавливает программу: она продолжает работать, но получает мало сообщений или не получает вовсе, и причину показывает только записанная в лог ошибка: Api(TerminatedByOtherGetUpdates) для второй копии, Api(InvalidToken) для отозванного токена. См. Как исправить ошибку 409 Conflict у Telegram-бота.
  • Вебхук, оставшийся на боте, удаляется за вас. repl и Dispatcher::dispatch() запускают long polling с тайм-аутом 10 секунд и сначала вызывают deleteWebhook, если задан вебхук, сохраняя ожидавшие сообщения. Функции webhooks в teloxide требуют публичного HTTPS-адреса, которого в наших тарифах пока нет, поэтому используйте repl или dispatch().
  • Чистая остановка. Панель останавливает бота на Rust сигналом Ctrl+C (SIGINT). repl включает обработчик Ctrl+C в teloxide, который останавливает поллинг и сообщает Telegram, какие сообщения уже получены, чтобы следующий запуск не получил их снова. Если вы используете собственный Dispatcher, добавьте .enable_ctrlc_handler() в builder, как это делают примеры teloxide.
  • Обновления. В типе Rust Bot нет поля Пакеты и источника Git: ваши крейты находятся внутри программы. Чтобы обновить, удалите старую программу в разделе Files, загрузите новую сборку и перезапустите. Со ссылкой для скачивания опубликуйте новую сборку по этой ссылке, удалите программу в разделе Files и нажмите Запустить.

Запуск самостоятельно на Linux VPS

Скопируйте собранную программу на VPS; Rust там не нужен. Программа, собранная со стандартными функциями, требует OpenSSL 3, который есть в Debian 12 и 13 и Ubuntu 22.04 и 24.04, и glibc не старше той, что в системе, где вы собирали. Сборке с musl не нужно ни то ни другое.

Создайте пользователя для бота, положите программу в его папку и храните токен в файле, который может читать только root:

sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo install -o mybot -m 755 bot /opt/mybot/bot
sudo sh -c 'echo "TELOXIDE_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env

Создайте /etc/systemd/system/mybot.service:

[Unit]
Description=teloxide Telegram bot
Wants=network-online.target
After=network-online.target

[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/opt/mybot/bot
Restart=always
RestartSec=5
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

Запустите службу сейчас и при каждой загрузке, затем следите за её выводом:

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo journalctl -u mybot -f

KillSignal=SIGINT заставляет systemctl stop посылать Ctrl+C, который перехватывает обработчик teloxide для чистой остановки; сигнал systemd по умолчанию, SIGTERM, завершает программу сразу. Restart=always запускает бота снова после падения или выхода. Сначала остановите любую другую копию, иначе Telegram ответит 409 Conflict.

Свой сервер или тариф для ботов

На VPS, которым вы управляете сами:

  • Обновления и безопасность операционной системы, а также версии OpenSSL и glibc, подходящие вашей сборке.
  • Копирование каждой новой сборки, файла службы, файла с токеном и его прав доступа.
  • Чтение journalctl, чтобы выяснить, почему бот остановился.
  • Резервные копии данных бота.

Взамен VPS запускает что угодно, и вы можете дать ему домен с HTTPS для вебхука.

На тарифе для ботов PlayNHost это делает за вас панель:

  • Образ Debian, который запускает программу для Linux x86-64, и проверка при старте, которая сообщает об этом, если файл собран для Windows или macOS.
  • Загрузка в разделе Files или ссылка для скачивания, которую сервер берёт при старте.
  • Токен, проверенный в Telegram, хранится в зашифрованном виде и передаётся вашей программе как TELOXIDE_TOKEN.
  • Повторный запуск бота после падения. Если он падает снова в течение минуты, он остаётся остановленным, а Console объясняет причину.
  • Баннеры над Console, которые называют причину, когда Telegram отклоняет токен или работает другая копия, и кнопка Удалить вебхук во вкладке Telegram.

Частые вопросы

Почему мой бот на teloxide вообще ничего не выводит?

teloxide пишет через крейт log и ничего не выводит, пока не настроен логгер. Вызовите pretty_env_logger::init() (или другой логгер) в начале main, как это делает бот выше. Ваши собственные строки println! всегда видны в Console.

Нужна ли мне функция webhooks в teloxide?

Нет. Вебхуку нужен публичный HTTPS-адрес, которого в наших тарифах пока нет. repl и dispatch() используют long polling, которому адрес не нужен: бот сам запрашивает у Telegram новые сообщения. Они также удаляют вебхук, оставленный на боте прежним хостингом.

Может ли сервер скомпилировать мой код на Rust?

Нет. Тип Rust Bot запускает готовую программу и ничего не компилирует, поэтому вся память вашего тарифа достаётся боту. Собирайте на своём компьютере или в workflow GitHub Actions, прикрепите программу к релизу и укажите ссылку на файл в поле Ссылка для скачивания (необязательно).

Тратит ли бот на teloxide меньше памяти, чем бот на Python?

Сравните цифры: в том же тесте python-telegram-bot 22.8 занял 44 МБ, а aiogram 3.31.0 занял 173 МБ, против 13 МБ у teloxide. Все три помещаются в тариф STARTER на 0.5 ГБ с запасом для вашего кода, так что выбирайте язык, на котором хотите писать.

Готовы запустить бота на teloxide круглосуточно? Смотрите тарифы на странице хостинга Telegram-ботов.

Ваш бот уже у другого хостинга? Перенесите его к нам

ПОСЛЕДНИЕ БЛОГИ