Телеграм-бот на PHP для оповещений о выходе новых версий
Автоматические оповещения о релизах давно стали частью рабочего процесса в командах разработки. Пользователи хотят сразу узнавать о новых возможностях, исправлениях и изменениях, а разработчикам удобно иметь единый канал, куда стекаются все сведения о публикациях. Телеграм-бот легко берёт на себя роль такого посредника: он работает круглосуточно, не требует установки отдельного приложения и принимает сообщения даже на слабых каналах связи.
В материале разобран путь создания простого, но надёжного бота на чистом PHP с минимальным набором зависимостей. Используются Composer, HTTP-клиент Guzzle и встроенный драйвер SQLite для хранения подписчиков. Полученный код подходит для интеграции с любым Git-хостингом через вебхуки, а при необходимости легко расширяется командами, клавиатурами и форматированием.
| Способ взаимодействия с Bot API | Сильные стороны | Слабые стороны |
|---|---|---|
| Long polling | Не нужен публичный адрес, простая отладка | Постоянные запросы к серверу Telegram, задержка до нескольких секунд |
| Webhook | Мгновенная доставка событий, экономный расход ресурсов | Требуется HTTPS-домен и валидный сертификат |
| Готовая библиотека (irazasyed/telegram-bot-sdk) | Поддержка inline-клавиатур, медиа, обновлений «из коробки» | Избыточна для узких задач, сложнее кастомизировать |
| Собственный класс поверх Guzzle | Полный контроль над запросами, минимум внешнего кода | Нужно самостоятельно описывать маршрутизацию и обработку ошибок |
Подготовка рабочего окружения
Прежде чем приступать к коду, требуется установить интерпретатор PHP версии 8.1 и выше, менеджер зависимостей Composer, а также локальный веб-сервер для тестирования вебхуков. На Linux-дистрибутивах всё ставится через стандартные пакетные менеджеры, на Windows удобно воспользоваться сборкой OpenServer или Laragon. Для хранения списка подписчиков подойдёт файл SQLite — он не требует отдельного сервера баз данных и легко переносится между окружениями.
После установки окружения создаётся пустая директория проекта и инициализируется файл composer.json. В секцию require добавляется пакет guzzlehttp/guzzle, через который будут выполняться все обращения к Bot API. Команда composer install подтянет HTTP-клиент и его зависимости. На этом подготовительный этап завершён, и можно переходить к регистрации собственного бота.
Использовать лучше всего редактор с поддержкой PHP Intelephense или PhpStorm — они подсказывают сигнатуры методов Guzzle и подсвечивают ошибки типов. Версии зависимостей фиксируются в composer.lock, который коммитится в репозиторий: это гарантирует, что локальная сборка совпадает с рабочей. Для Git подойдёт классический .gitignore с исключениями vendor/, .env и storage/*.sqlite.
Создание бота в BotFather и получение токена
Любой бот в Телеграме создаётся через официального бота @BotFather. Достаточно отправить ему команду /newbot, придумать отображаемое имя и уникальный ник, оканчивающийся на bot. В ответ придёт токен — длинная строка вида 123456:ABC-DEF.... Этот токен фактически является паролем: с его помощью бот отправляет сообщения, читает обновления и управляет своим профилем. Хранить токен следует в файле .env, который добавляется в .gitignore, а в коде обращаться к нему через переменные окружения.
Дополнительно через BotFather задаётся аватар, краткое описание и список команд. Параметр About помогает пользователям понять назначение бота ещё до первого взаимодействия. Команды /start, /subscribe, /unsubscribe и /release объявляются в меню, чтобы Телеграм подсказывал их при вводе слеша. После этого бот сразу появляется в поиске и готов принимать сообщения.
Архитектура проекта и загрузка конфигурации
Структура каталогов выглядит компактно: в корне лежат index.php (точка входа для вебхуков), bot.php (логика обновлений), каталог src с классами TelegramClient, SubscriberRepository и ReleaseNotifier, а также директория storage для базы SQLite. Файл .env содержит токен бота, путь к БД и при необходимости секрет вебхука.
Загрузка конфигурации выполняется один раз в точке входа. Простейший вариант — ручной парсинг .env в массив, но удобнее подключить пакет vlucas/phpdotenv. Класс TelegramClient принимает токен через конструктор и предоставляет метод sendMessage, инкапсулирующий работу с Guzzle. Такой подход изолирует внешний API от остального кода и упрощает модульное тестирование.
Маршрутизация запросов реализуется прямо в index.php через match-выражение. Команда /start обрабатывается отдельно от обычных сообщений, а секретный путь /webhook принимает только POST-запросы от Git-хостинга. Любой неавторизованный вызов отбрасывается с кодом 403, что защищает бота от подделок. Для отладки удобно временно логировать всё входящее в файл debug.log.
Отправка сообщений через Telegram Bot API
Telegram Bot API представляет собой набор HTTPS-эндпоинтов. Базовый адрес — https://api.telegram.org/bot<TOKEN>/, а конкретный метод приписывается в конце, например /sendMessage. Запрос выполняется методом POST, тело содержит JSON с обязательными полями chat_id и text. Через Guzzle это выглядит так:
$response = $client->post($baseUrl.'sendMessage', [
'json' => [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'MarkdownV2',
],
]);
Telegram возвращает объект Message, который полезно логировать для отладки. При ошибке приходит код ответа 400 или 403 с описанием, чаще всего из-за неверного chat_id или попытки писать пользователю, заблокировавшему бота. Все исключения перехватываются и записываются в журнал, чтобы администратор видел, кому не удалось доставить оповещение. При сетевых сбоях Guzzle автоматически повторяет запрос, что повышает надёжность рассылки.
Подписка пользователей и хранение данных
Бот должен помнить, кто подписан на рассылку. Простейшая таблица SQLite содержит три поля: chat_id (целое число), username (строка, может быть пустой) и subscribed_at (временная метка). Команда /start заносит пользователя в базу, /unsubscribe удаляет запись, а /subscribers (доступна только администратору) выводит количество подписчиков.
Класс SubscriberRepository работает через PDO и предоставляет методы add, remove, getAll и count. Так как SQLite поддерживает блокировки на уровне файла, при большом потоке подписок стоит позднее переключиться на MySQL или PostgreSQL — интерфейс репозитория останется прежним. Дополнительно полезно добавить проверку флага is_bot и language_code, чтобы фильтровать тестовые аккаунты и подстраивать язык сообщений. При первом запуске файл базы создаётся автоматически через CREATE TABLE IF NOT EXISTS.
Связь с Git-хостингом через вебхуки
Чтобы бот автоматически узнавал о новом релизе, настраивается webhook в GitHub, GitLab или Gitea. В настройках репозитория указывается URL вида https://example.com/index.php?event=release и секрет, совпадающий со значением в .env. При публикации нового тега хостинг отправляет POST-запрос с JSON-описанием релиза: название, описание, автор, ссылка на архив.
Скрипт index.php проверяет заголовок X-GitHub-Event (или аналог для других хостингов) и при значении release парсит тело запроса. Из полезной нагрузки извлекаются имя релиза, список изменений и URL страницы. Класс ReleaseNotifier формирует красиво отформатированное сообщение с визуальным префиксом, разметкой MarkdownV2 и кнопкой «Скачать», после чего вызывает SubscriberRepository::getAll и рассылает уведомление через TelegramClient::sendMessage. Чтобы избежать дублей, идентификатор релиза сохраняется в отдельной таблице и пропускается при повторной отправке.
Развёртывание и сопровождение
Готовый бот размещается на VPS с PHP-FPM и Nginx. Для приёма вебхуков требуется валидный TLS-сертификат — проще всего получить его через Let's Encrypt с автоматическим обновлением. Nginx проксирует запросы к index.php, а в случае ошибок возвращает 500, чтобы хостинг повторил отправку. Постоянная работа процесса обеспечивается через systemd-юнит с автоматическим перезапуском.
Сопровождение сводится к мониторингу логов, периодической ротации базы SQLite и обновлению зависимостей. Если в команде несколько проектов, бот дополняется командами /project add, /project list и /project set, что превращает его в универсальный центр уведомлений. Такой подход масштабируется без переписывания ядра, остаётся прозрачным для разработчика и удобным для конечных пользователей.
Отдельное внимание стоит уделить безопасности. Токен бота и секрет вебхука никогда не публикуются в открытом доступе, доступ к серверу ограничивается по SSH-ключам. Каждые несколько месяцев проверяются обновления PHP и библиотек, чтобы устранить уязвимости. При росте аудитории логичным шагом становится перенос подписчиков из SQLite в полноценную СУБД — это упрощает резервное копирование и параллельные рассылки.