Поднимаем сервер Telegram Local Bot API

Сервер Telegram Local Bot API

Как известно, у облачной платформы Telegram Bot Api есть ограничения. В зависимости от популярности и функционала вашего Telegram бота, вы можете столкнуться с несколькими распространенными проблемами:

  • у вебхука есть лимит на 40 одновременных подключений, это значит, что при 40+ пользователей, использующих ваш бот в одно и то же время, он может начать “лагать” независимо от мощности вашего сервера;
  • бот не может загружать файлы (метод getFile), размером более 20 Мб;
  • бот не может отправлять пользователям файлы (методы send*), размером более 50 Мб;

Чтобы обойти эти ограничения, вы можете запустить свой собственный сервер Local Bot API и тогда получите следующие преимущества:

  • Скачивание файлов без ограничения по размеру
  • Загрузка файлов размером до 2000 Мб
  • Загрузка файлов, используя локальный путь или схему URI file://
  • Использование http для вебхука
  • Использование любого локального ip-адреса для вебхука
  • Использование любого порта для вебхука
  • Максимальное количество подключений для вебхука до 100000
  • Абсолютный локальный путь в качестве значения поля file_path без необходимости скачивания файла после запроса getFile

Компиляция

Чтобы не привязываться к какой-то конкретной операционной системе, я советую вам воспользоваться генератором инструкций для компиляции, который любезно предоставили разработчики. Перейдите по ссылке, выберите ОС и дистрибутив, затем место сохранения бинарника после сборки (telegram-bot-api/bin или /usr/local/bin) и получите список инструкций, которые нужно выполнить в вашей ОС. Старайтесь вводить команды по одной, чтобы убедиться в успешности их выполнения. Обратите внимание, что процесс компиляции на виртуальных машинах Linux длится примерно час, по крайней мере у меня было именно так. Компиляция по предоставленным инструкциям не вызовет трудностей, просто выполняйте команды по очереди и всё получится.

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

Готовые бинарники, если вы не хотите заниматься компиляцией

Вы можете скачать архив с бинарниками telegram-bot-api (v7.7 от 07.07.2024), которые я скомпилировал для вас. В архиве лежат бинарники для следующих ОС: Alpine 3.17, CentOS Stream 9, Debian 11, Debian 12, Fedora 37, Ubuntu 22.04, Ubuntu 24.04. Архитектура x86-64 (amd64).

Перед запуском готового исполняемого файла telegram-bot-api на некоторых ОС, вам потребуется установить:

# для Debian 11-12:
$ apt install libc++-dev

# для Ubuntu 22.04:
$ apt install libc++-14-dev

# для Ubuntu 24.04
$ apt install libc++-18-dev

Для запуска сервера вам понадобится api_id и api_hash. Вы можете получить их здесь. Обратите внимание, что система очень строга к названию приложения, поэтому пробуйте разные варианты, пока не получится.

Теперь можно сделать тестовый запуск сервера. Я буду считать, что вы установили сервер в /usr/local/bin, а если это не так, просто укажите или замените путь на свой в дальнейших командах статьи.

Запускаем сервер:

telegram-bot-api --local --api-id=<api_id> --api-hash=<api_hash>

Если никаких ошибок не появилось и сервер занял собой терминал, значит все хорошо. Чтобы окончательно убедиться, откройте еще один терминал и выполните команду curl http://localhost:8081

В ответ вы должны увидеть следующее:

{"ok":false,"error_code":404,"description":"Not Found"}

Если всё так, значит сервер работает корректно и вы пока можете закрыть его при помощи Ctrl+C.

Настройка

Под спойлером находится список известных параметров, которые вы можете указывать при запуске telegram-bot-api. Они позволяют настроить сервер для различных условий работы, оптимизируя производительность и безопасность. Обратите внимание, что некоторые параметры могут быть специфичны для конкретных версий сервера. Для обеспечения максимальной производительности вашего бота, я рекомендую запускать сервер с параметром --local на той же машине, где находится ваш бот и подключать вебхук по локальной сети и схеме http.

Список параметров запуска

Основные параметры:

--api-id – Идентификатор приложения для доступа к Telegram API. Обычно используется для аутентификации приложения в Telegram API.
--api-hash – Хеш идентификатора приложения для доступа к Telegram API. Работает в паре с api-id для аутентификации.
--http-ip-address – Локальный адрес, по которому будут приниматься HTTP соединения. По умолчанию принимаются подключения по любому локальному IPv4.
--http-port – Порт для HTTP-сервера, через который сервер будет принимать запросы. По умолчанию: 8081.
--http-stat-ip-address – Локальный адрес, по которому будут приниматься HTTP соединения к серверу статистики. По умолчанию принимаются подключения по любому локальному IPv4.
--http-stat-port – Порт для HTTP сервера статистики, который используется для мониторинга состояния и работы сервера. По умолчанию: 0 (выкл).
--local – Параметр, указывающий, что сервер должен обслуживать только локальные запросы. Это повышает уровень безопасности, ограничивая доступ к API.
--dir – Рабочая директория сервера, где будут храниться все файлы, связанные с работой сервера.
--temp-dir – Директория для временных файлов, используемых сервером.

Дополнительные параметры:

--log – Путь к файлу, куда будут записываться логи работы сервера.
--verbosity – Уровень детализации логов, которые будет записывать сервер.
--memory-verbosity – Уровень детализации логов по использованию памяти.
--log-max-file-size – Максимальный размер файла лога перед его архивацией или удалением. По умолчанию 2 Гб.
--max-connections – Максимальное количество одновременных соединений, которые может обрабатывать сервер. По умолчанию: 0 (без ограничений).
--cpu-affinity – Устанавливает маску CPU, позволяя связать выполнение процессов сервера с определенными ядрами процессора. По умолчанию: 0 (использует все доступные ядра).
--main-thread-affinity – Устанавливает маску CPU для привязки основного потока к конкретному ядру. По умолчанию использует значение cpu-affinity
--max-webhook-connections – Ограничение количества соединений для вебхуков на одного бота. По умолчанию: 100 в режиме --local, иначе 40.
--username – Имя пользователя, под которым будет запущен сервер.
--groupname – Группа пользователя, под которой будет запущен сервер.
--proxy – Прокси сервер для исходящих запросов вебхука в формате http://host:port

Создаем сервис для автозапуска Local Bot API

Если вы уже определились с параметрами, которые будете использовать для запуска сервера, рекомендую сразу создать сервис для автоматического запуска.

nano /etc/systemd/system/telegram-bot-api.service

Добавьте следующий код:

[Unit]
Description=Telegram Bot API Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/lib/telegram-bot-api
ExecStart=/usr/local/bin/telegram-bot-api --local --api-id=<api_id> --api-hash=<api_hash> --max-webhook-connections=1000
SyslogIdentifier=telegram-bot-api
Restart=always
User=nobody
Group=nogroup

[Install]
WantedBy=multi-user.target

Не забудьте указать ваши api_id и api_hash, а также другие параметры запуска, какие вам требуются. Перед запуском сервиса, вам необходимо создать ту рабочую директорию, которую вы указали в файле сервиса. Это может быть любая директория, не обязательно /var/lib/telegram-bot-api. В файле сервиса укажите те же User и Group, под которыми работает ваш бот, чтобы у него не было проблем с доступом к загруженным медиа-файлам. Если ваш бот работает под root (не рекомендуется) и сервер BOT API тоже будет под root, то в файле сервиса можно не указывать параметры User и Group.

Запускаем сервис, добавляем в автозагрузку и сразу проверяем статус:

systemctl start telegram-bot-api
systemctl enable telegram-bot-api
systemctl status telegram-bot-api
Статус сервиса Telegram Local Bot API

Если статус показывает примерно то же, что на скриншоте, значит всё получилось. Вы можете перезагрузить виртуальную машину и убедиться, что telegram-bot-api будет запущен автоматически.

Перенос бота на Local Bot API

Чтобы переключить вашего бота на локальный сервер api, сначала нужно отключить его от облачной платформы Telegram Bot Api. Для этого существует метод logOut. Вы можете просто открыть в браузере ссылку, заменив <BOT_TOKEN> на настоящий токен вашего бота:

https://api.telegram.org/bot<BOT_TOKEN>/logOut

В ответе вы увидите true в двух параметрах.

Теперь вы можете добавить бота на ваш локальный сервер api. Если ваш бот написан с использованием библиотеки, откройте документацию к библиотеке и найдите там код, позволяющий указать свой адрес api сервера. Например для aiogram это написано здесь, для pyTelegramBotAPI (TeleBot) здесь, а для PHP Telegram Bot здесь. Если же у вас полностью самописный бот, то просто замените в своих скриптах адрес, на который бот делает запросы и вместо https://api.telegram.org укажите http://localhost:8081

Если вы используете вебхук, то выполните setWebhook с необходимыми параметрами и запустите вашего бота. Если вы используете long-polling, то просто запустите бота и он начнет опрашивать уже ваш локальный сервер.

Работа с файлами в Local Bot API

Как только вы переключите ваш бот на локальный сервер api, в рабочей директории появится папка с именем, равным токену вашего бота. Когда ваш бот будет получать изображения и другие файлы от пользователей, они будут находиться именно там, разложенные по папкам photos, documents и т.п.

Если telegram-bot-api работает в режиме --local, то для получения файлов от пользователей, вам теперь достаточно лишь метода getFile. Если в коде вашего бота вы склеивали https://api.telegram.org/file/bot/<token>/ с file_path из getFile и скачивали файл, то вам потребуется внести правки и избавиться от скачивания файлов, ведь getFile сразу будет выдавать абсолютный локальный путь до файла.

Обратите внимание, что у пользователя, от имени которого работает ваш бот должны быть права на чтение в рабочей директории telegram-bot-api, иначе он не сможет получать файлы.

На этом у меня всё. Надеюсь, что эта статья была вам полезна 😉