Искать в Базе знаний

Размещение Telegram-бота на PHP

Подходы к разработке

В одной из статей мы рассказывали о том, как разместить Telegram-бота на Python. Здесь же расскажем как это сделать на языке программирования PHP.
В случае с ботом на PHP есть два метода: long polling и webhook.
Метод long polling удобен своей простотой. Он не требует домена, SSL-сертификата и настройки веб-сервера. Отлично подходит для небольших ботов с малой нагрузкой, а также для тестов или обучения. Однако из-за архитектурных особенностей он потребляет много ресурсов сервера и может реагировать на команды пользователей бота с задержкой. Данный подход считается устаревшим.
У webhook чуть более сложный процесс настройки: для него нужен рабочий домен, который разрешается в IP-адрес вашего бокса, SSL-сертификат и веб-сервер по типу nginx или Apache. Однако бот, разработанный с помощью webhook, потребляет куда меньше ресурсов и хорошо подходит для высоконагруженных проектов. Такой подход считается современным.
В этой статье мы подробно разберем оба подхода. Приступим!

Метод long polling

Установка зависимостей

Для начала обновим пакетный менеджер apt и все системные библиотеки:
root@box-123456:~# sudo apt update && sudo apt upgrade -y
Теперь установим необходимые для работы бота зависимости:
root@box-123456:~# sudo apt install php-cli php-mbstring php-curl php-xml -y
root@box-123456:~# sudo apt install composer -y

Размещение логики бота

Создадим корневой каталог для размещения файлов бота, а также индексный файл бота:
root@box-123456:~# mkdir /opt/bot && cd /opt/bot
root@box-123456:~/opt/bot# touch bot.php
При написании кода бота стоит учесть, что метод long polling выполняет код один раз. Чтобы бот работал постоянно, логику бота стоит обернуть в бесконечный цикл while(true).
Пример структуры конструкции while(true):
<?php
require __DIR__ . '/vendor/autoload.php';
$telegram = new Longman\TelegramBot\Telegram('ВАШ_API_ТОКЕН', 'ИМЯ_БОТА_БЕЗ @');
while (true) {
    try {
        $telegram->handleGetUpdates();
        
        sleep(1);
    } catch (Exception $e) {
        echo "Ошибка: " . $e->getMessage();
        sleep(5);
    }
}
?>
Получить API-токен и название бота можете с помощью официального бота Telegram @BotFather.
Инициализируем composer, чтобы у PHP был доступ к установленным зависимостям:
root@box-123456:~/opt/bot# composer require longman/telegram-bot

Настройка непрерывной работы бота

Для непрерывной работы бота устанавливаем Supervisor:
root@box-123456:~/opt/bot# sudo apt install supervisor -y
Создаем файл конфигурации для Supervisor:
root@box-123456:~/opt/bot# vim /etc/supervisor/conf.d/telegram_bot.conf
и указываем такие параметры:
[program:telegram_bot]
command=php /opt/bot/bot.php
directory=/opt/bot
autostart=true
autorestart=true
user=root
stderr_logfile=/var/log/telegram_bot.err.log
stdout_logfile=/var/log/telegram_bot.out.log
Пояснение:
  • command — путь до исполняемого файла бота;
  • directory — путь до каталога, где хранятся файлы бота;
  • stderr_logfile — путь до журнала ошибок;
  • stdout_logfile — путь до журнала стандартного вывода.
Запускаем Supervisor:
root@box-123456:~/opt/bot# sudo supervisorctl reread && sudo supervisorctl update
Если в коде бота нет ошибок, то он сразу заработает. Если необходима отладка, то стоит посмотреть трейс ошибки в журнале ошибок.

Метод Webhook

Метод webhook требует зарегистрированного домена/поддомена. Перед размещением бота не забудьте направить ваш домен на IP-адрес бокса
123.456.78.910 ваш_домен
123.456.78.910 www
Проверить в какой адрес разрешается домен можно утилитой dig
dig a ваш_домен +short
# Должен вернуть IP вашего бокса, например: 123.456.78.910 
# Если вернул пустоту или чужой IP — ждите, DNS ещё не обновился
После того, как домен будет разрешаться в нужный IP-адрес, можно приступить к размещению!
Итак, приступим! Обновляем систему и устанавливаем необходимые зависимости:
root@box-123456:~# sudo apt update && sudo apt upgrade -y
root@box-123456:~# sudo apt install -y apache2 php php-cli php-curl php-json php-mbstring curl git unzip
Включаем необходимые модули Apache:
root@box-123456:~# sudo a2enmod rewrite
root@box-123456:~# sudo a2enmod ssl
root@box-123456:~# sudo systemctl restart apache2
Создаем корневую директорию для бота и задаем владельца:
root@box-123456:~# sudo mkdir -p /opt/bot
root@box-123456:~# sudo chown -R www-data:www-data /opt/bot
root@box-123456:~# sudo chmod 755 /opt/bot
root@box-123456:~# sudo chmod 644 /opt/bot/bot.php
Настраиваем конфигурацию Apache
root@box-123456:~# sudo nano /etc/apache2/sites-available/bot.conf
Конфигурация должна выглядеть так:
<VirtualHost *:80>
    ServerName ваш_домен
    # корневая директория бота
    DocumentRoot /opt/bot 
    
    # корневая директория бота
    <Directory /opt/bot> 
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    
    
    ErrorLog ${APACHE_LOG_DIR}/bot_error.log
    CustomLog ${APACHE_LOG_DIR}/bot_access.log combined
И активируем:
root@box-123456:~# sudo a2ensite bot.conf
root@box-123456:~# sudo a2dissite 000-default.conf
root@box-123456:~# sudo systemctl reload apache2
Устанавливаем certbot и выпускаем SSL-сертификат Let’s Encrypt для домена:
root@box-123456:~# sudo apt install -y certbot python3-certbot-apache
root@box-123456:~# sudo certbot --apache -d ваш_домен
Сообщение, которое сообщает об успешной установке сертификата:
Successfully deployed certificate for ваш_домен to /etc/apache2/sites-available/bot-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://ваш_домен