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

Как запустить бота на python-telegram-bot 24/7

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

Чтобы запустить бота на python-telegram-bot 24/7, держите его на машине, которая всегда включена, а не на своём компьютере: на Linux VPS со службой systemd, которая запускает его снова после сбоя или перезагрузки, или на тарифе для ботов PlayNHost (от US$1.99 в месяц, см. хостинг Telegram-ботов), где вы загружаете код, вставляете токен и нажимаете Start. В нашем тесте бот на python-telegram-bot 22.8 в покое занимал около 44 МБ памяти; наш самый маленький тариф для ботов, STARTER, даёт 0,5 ГБ. Оба способа используют long polling: run_polling() запрашивает у Telegram новые сообщения, поэтому боту не нужен публичный адрес. Шаги в PlayNHost:

  1. В Telegram отправьте /newbot боту @BotFather и скопируйте полученный токен.
  2. На странице хостинг Telegram-ботов нажмите Создать сервер у нужного тарифа. В окне заказа ответьте на Для какой платформы ваш бот? выбором Telegram и выберите Python.
  3. Откройте свой сервер в панели. Карточка Настройка бота на странице Обзор открывается на шаге Подключение к Telegram; его первый шаг, Что запускается, должен показывать Этот бот запускает Python Bot.
  4. На шаге Подключение к Telegram вставьте токен и нажмите Подключение. Проверьте показанное имя бота и нажмите Да, продолжить.
  5. На шаге Ваш код нажмите Загрузить файлы, чтобы открыть Files, и загрузите bot.py и requirements.txt, либо нажмите Подключить Git. Кода ещё нет? Создать стартового бота напишет для вас бота на python-telegram-bot 22.
  6. На странице Бот, в разделе Код, проверьте, что Файл запуска это файл, который вызывает run_polling() (по умолчанию bot.py).
  7. Нажмите Запустить бота, откройте Console и дождитесь Logged in as @your_bot. Индикатор на странице Обзор сменится на Онлайн в Telegram. Отправьте своему боту /start.

Первый запуск идёт дольше, пока pip устанавливает python-telegram-bot. После этого установка повторяется только при изменении файла requirements, дополнительных пакетов или версии Python, либо раз в сутки. Пошагово со скриншотами: Как запустить Telegram-бота на хостинге.

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

Мы запустили три Python-библиотеки для Telegram на одном из наших серверов, в одноразовых контейнерах, настроенных так, как панель запускает Python-бота: Python 3.12 (Среда выполнения, помеченная как рекомендуемая), пакеты установлены той же командой pip, лимит памяти 1 ГБ и одно ядро процессора.

БиблиотекаВерсияПамять в покоеОт запуска до ответа TelegramУстановленный размер с зависимостями
python-telegram-bot22.844 МБ0,9 с12,3 МБ
aiogram3.31.0173 МБ4,3 с33,9 МБ
pyTelegramBotAPI4.37.140 МБ0,7 с21,9 МБ
Один Python 3.129 МБ

Каждый бот загружал библиотеку и спрашивал у Telegram, кто он, с поддельным токеном (python-telegram-bot: Application.initialize()). Память это то, что занимали процессы бота через 15 секунд после отказа Telegram принять токен; время запуска считается от старта Python до момента, когда библиотека сообщает этот ответ, поэтому оно включает один обмен с Telegram. Оба значения это медиана трёх запусков после одного прогревочного.

Эти цифры это нижняя граница библиотеки: без чатов, без работающих обработчиков, без кэша. Ваш собственный код, данные, которые он держит в памяти, и число обслуживаемых чатов добавляются сверху, поэтому выбирайте тариф по тому, что делает ваш бот. Наша прежняя страница python-telegram-bot или aiogram на PlayNHost измеряла другую конфигурацию (Python 3.13, готовый к запуску собранный бот), поэтому её цифры нельзя сравнивать с этими.

Минимальный бот на python-telegram-bot

Он отвечает на /start, читает токен, который выдаёт панель, и печатает строку о готовности. Укажите библиотеку в requirements.txt:

python-telegram-bot>=22,<23

А код поместите в bot.py:

import os

from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.effective_message.reply_text("Hello! I am running on PlayNHost.")


async def post_init(application: Application) -> None:
    print(f"Logged in as @{application.bot.username}")


def main() -> None:
    application = (
        Application.builder()
        .token(os.environ["TELEGRAM_BOT_TOKEN"])
        .post_init(post_init)
        .build()
    )
    application.add_handler(CommandHandler("start", start))
    application.run_polling(allowed_updates=Update.ALL_TYPES)


if __name__ == "__main__":
    main()

post_init выполняется после инициализации приложения, а именно тогда python-telegram-bot проверяет токен в Telegram, поэтому Logged in as @your_bot появляется только после того, как Telegram принял токен. Панель читает эту строку, чтобы показать Онлайн в Telegram. Панель передаёт токен вашему коду как TELEGRAM_BOT_TOKEN, а также как BOT_TOKEN, TOKEN и TELEGRAM_TOKEN, так что os.environ["TOKEN"] тоже работает, если вы начинаете с примеров библиотеки, где используется заглушка "TOKEN".

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

В нашем тесте с токеном, который Telegram отвергает, тестовый бот напечатал:

InvalidToken: The token `1000000000:AAFakeTokenForAMemoryTestNotReal00000` was rejected by the server.

python-telegram-bot проверяет токен до начала polling, поэтому бот выше сразу останавливается с кодом выхода 1. Сначала консоль показывает Network Retry Loop (Bootstrap Initialize Application): Invalid token. Aborting retry loop. с трассировкой, затем трассировку самой ошибки, последняя строка которой: telegram.error.InvalidToken: The token `...` was rejected by the server. В PlayNHost панель показывает над консолью Telegram не принял токен вашего бота с кнопкой Заменить токен. Учтите, что обе трассировки содержат сам токен: не публикуйте этот вывод консоли нигде в открытом доступе.

Чтобы исправить, скопируйте токен заново: в @BotFather отправьте /mybots, выберите своего бота, затем API Token. Вставьте его на странице Бот, в разделе Telegram, в поле Токен, и снова запустите бота. Если токен отозван, когда бот уже работает в режиме polling, python-telegram-bot записывает Network Retry Loop (Polling Updates): Invalid token. Aborting retry loop. и прекращает polling, но процесс продолжает работать, так что бот выглядит запущенным, хотя ничего не отвечает. Панель показывает тот же баннер.

Что хостингу нужно знать о python-telegram-bot

  • Имена пакета и импорта: вы устанавливаете python-telegram-bot и импортируете telegram и telegram.ext.
  • Версия Python: python-telegram-bot 22.8 требует Python 3.10 или новее. Среда выполнения в разделе Код предлагает версии с 3.10 по 3.14, где 3.12 помечена как рекомендуемая, так что подходит любой вариант.
  • Webhook, оставшийся от другого хостинга: перед началом polling run_polling() удаляет любой webhook, заданный для бота, поэтому бот, перенесённый с хостинга с webhook, работает без дополнительного кода. Сообщения, ожидающие в Telegram, сохраняются, если не передать drop_pending_updates=True.
  • Логирование: python-telegram-bot записывает свой запуск на уровне INFO, который Python не показывает, пока вы не настроите логирование, поэтому бот выше печатает собственную строку о готовности. С logging.basicConfig(level=logging.INFO) он записывает INFO:telegram.ext.Application:Application started, и панель тоже считает это готовностью. Если вы так делаете, добавьте также logging.getLogger("httpx").setLevel(logging.WARNING), как в примерах самой библиотеки: на уровне INFO HTTP-библиотека записывает каждый URL запроса, а URL запросов Telegram содержат ваш токен.
  • Запланированные задачи: для JobQueue нужен дополнительный пакет. Напишите python-telegram-bot[job-queue]>=22,<23 в requirements.txt; без него application.job_queue равен None, а библиотека предупреждает No `JobQueue` set up.
  • Вторая копия: когда другая копия делает polling с тем же токеном, Telegram отвечает 409 Conflict. python-telegram-bot записывает Exception happened while polling for updates. и продолжает повторять попытки, так что бот выглядит работающим, но пропускает сообщения. Панель показывает Ваш бот работает ещё и в другом месте. См. Как исправить ошибку 409 Conflict у Telegram-бота.

Самостоятельный хостинг на Linux VPS

В Debian или Ubuntu установите Python, создайте пользователя для бота и установите библиотеку в виртуальное окружение. Проверьте, что python3 --version показывает 3.10 или новее.

sudo apt update
sudo apt install -y python3 python3-venv
sudo useradd --system --create-home --home-dir /opt/tgbot --shell /usr/sbin/nologin tgbot
sudo cp bot.py requirements.txt /opt/tgbot/
sudo -u tgbot python3 -m venv /opt/tgbot/venv
sudo -u tgbot /opt/tgbot/venv/bin/pip install -r /opt/tgbot/requirements.txt

Положите токен в файл, который может читать только root. Откройте его командой sudo nano /etc/tgbot.env, напишите одну строку, сохраните, затем выполните sudo chmod 600 /etc/tgbot.env:

TELEGRAM_BOT_TOKEN=123456789:your-token-from-botfather

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

[Unit]
Description=Telegram bot (python-telegram-bot)
Wants=network-online.target
After=network-online.target

[Service]
User=tgbot
WorkingDirectory=/opt/tgbot
EnvironmentFile=/etc/tgbot.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/tgbot/venv/bin/python /opt/tgbot/bot.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

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

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

PYTHONUNBUFFERED=1 здесь важен: когда вывод Python идёт не в терминал, он буферизуется блоками, поэтому без этой настройки Logged in as может застрять в буфере и не попасть в журнал. systemctl stop tgbot отправляет SIGTERM, который run_polling() обрабатывает, чисто завершая работу. После изменения кода выполните sudo systemctl restart tgbot. Сначала остановите любую копию на своём компьютере, иначе Telegram ответит 409 Conflict.

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

  • На VPS, которым вы управляете сами: обновления системы, версия Python, виртуальное окружение, переустановка пакетов, файл unit, чтение журнала и замечание момента, когда бот перестаёт отвечать. Взамен у вас есть root, и вы можете запустить webhook, если добавите домен и HTTPS.
  • На тарифе для ботов панель делает это сама: устанавливает requirements.txt, когда он меняется, запускает бота снова после сбоя, проверяет токен в Telegram перед сохранением, передаёт его вашему коду под пятью именами, читает консоль и называет причину, когда бот перестаёт отвечать (отвергнутый токен, вторая копия, webhook), с кнопкой для токена и webhook. Наши тарифы для ботов пока не включают публичный HTTPS-адрес, поэтому боты там используют long polling, а именно это и делает run_polling().

См. также Как подключить базу данных MySQL к боту на python-telegram-bot (aiomysql).

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

Нужен ли webhook, чтобы бот на python-telegram-bot оставался онлайн?

Нет. run_polling() держит открытое соединение с Telegram и запрашивает новые сообщения, так что бот отвечает, пока работает процесс. Для webhook нужен публичный HTTPS-адрес, которого в наших тарифах для ботов пока нет. Перенос бота, который его использовал: Как перенести Telegram-бота на PlayNHost.

Почему мой токен появился в консоли?

Он появляется в двух частых местах: в сообщении InvalidToken, когда Telegram отвергает токен, и в строках запросов HTTP-библиотеки, когда логирование на уровне INFO. Установите для логгера httpx уровень WARNING, как показано выше. Наш стартовый бот также перехватывает InvalidToken и вместо этого печатает простую строку.

Можно ли использовать run_repeating и другие запланированные задачи?

Да, с дополнением job-queue в requirements.txt. Оно устанавливает APScheduler при следующем запуске, потому что файл requirements изменился. Задачи выполняются внутри процесса бота, поэтому работают, пока работает бот.

Использует ли стартовый бот python-telegram-bot?

Да. На Python-сервере Создать стартового бота записывает bot.py и requirements.txt с python-telegram-bot 22. Он отвечает на /start, печатает Logged in as @your_bot и не выводит токен в строках лога. Измените его как угодно и перезапустите.

python-telegram-bot работает на любом тарифе для ботов PlayNHost, начиная с STARTER (0,5 ГБ). Сравните тарифы и нажмите Создать сервер на странице хостинг Telegram-ботов.

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

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