В этом подробном руководстве мы с нуля погрузимся в процесс разработки собственного Telegram-бота, используя для этого возможности PHP и элегантность фреймворка Laravel. Благодаря своей продуманной архитектуре, выразительному синтаксису и обширной экосистеме Laravel представляет собой идеальную платформу для создания и последующего управления сложными ботами. Мы пройдем с вами весь путь: от самого первого шага — регистрации бота в Telegram — до развертывания и написания его логики на сервере под управлением Ubuntu 24.04.
Почему именно Laravel? Писать сложную логику на «чистом» PHP можно, но это долго и не всегда эффективно. Здесь на сцену выходит Laravel — PHP-фреймворк, который предоставляет готовую структуру и огромное количество удобных инструментов для разработки.
Laravel организует ваш PHP-код в элегантную и масштабируемую систему. Он берет на себя всю рутинную работу:
- Маршрутизация: легко направляет входящий запрос от Telegram к нужному участку кода (контроллеру).
- Работа с базой данных: позволяет без труда сохранять информацию о пользователях, их сообщениях или настройках.
- Обработка HTTP-запросов: предоставляет удобные инструменты для отправки ответных сообщений обратно в Telegram API.
- Очереди и задачи по расписанию: дает возможность выполнять долгие задачи (например, рассылку) в фоновом режиме, не замедляя ответы бота.
cloud
Регистрация бота и получение токена
Прежде чем мы напишем хотя бы одну строку кода, необходимо выполнить подготовительное, но крайне важное действие: зарегистрировать нашего будущего цифрового помощника в экосистеме Telegram и получить уникальный ключ доступа — API-токен.
- Запустите ваш клиент Telegram. В поисковой строке введите псевдоним
@BotFather
и выберите из результатов поиска официального управляющего бота, отмеченного синей галочкой верификации. - Инициируйте диалог: начните общение с ним, отправив команду
/newbot
. Это даст ему понять, что вы намерены создать нового бота. - Выберите имя и уникальный юзернейм: BotFather попросит вас последовательно придумать два имени. Первое — это публичное имя, которое будут видеть пользователи (оно может быть любым, даже с использованием пробелов и кириллицы). Второе — это технический юзернейм, который должен быть абсолютно уникальным в рамках всего Telegram, написан латиницей и обязательно заканчиваться на суффикс
bot
(например,MySuperLaravelBot
илиTestProject_bot
). - Сохраните токен доступа: сразу после того как вы подберете уникальный юзернейм, BotFather поздравит вас с успешным созданием бота и пришлет сообщение, содержащее токен. Этот токен представляет собой длинную случайную последовательность букв и цифр. Он является вашим секретным ключом для взаимодействия с Telegram Bot API. Скопируйте его и сохраните в надежном, недоступном для посторонних месте. Относитесь к нему как к паролю от очень важного аккаунта.
Поздравляем, теперь у вас есть бот в Telegram!
Установка необходимого программного обеспечения
Обновите системные пакеты:
sudo apt update && sudo apt upgrade -y
Для получения доступа к последним пакетам PHP нам нужно добавить репозиторий, поддерживаемый Ondrej Sury
. Используйте данную команду, чтобы добавить репозиторий.
sudo add-apt-repository ppa:ondrej/php
sudo apt update
Добавьте PPA для современных версий PHP, затем установите PHP 8.2 и нужные расширения:
sudo apt install -y php8.2 php8.2-fpm php8.2-mbstring php8.2-xml php8.2-sqlite3 php8.2-curl php8.2-zip php8.2-intl php8.2-bcmath
Установите Nginx и Composer:
sudo apt install -y nginx composer
Проверьте версию командой:
php -v
Вывод должен быть наподобие «PHP 8.2.x».
Настройка проекта Laravel и установка SDK
Теперь, когда у вас есть токен, можно приступать к настройке Laravel-проекта. Мы будем использовать пакет Telegraph — defstudio/telegraph
. Он имеет удобные команды artisan
для регистрации ботов и вебхуков.
Перейдите в папку для веб-сайтов:
cd /var/www
Создайте новый проект Laravel:
composer create-project laravel/laravel telegram-bot
Перейдите в папку проекта:
cd telegram-bot
Установите SDK через Composer:
composer require defstudio/telegraph:1.57.1
Чтобы пакет работал, Telegraph требует выполнения его миграций для создания таблиц telegraph_bots
и telegraph_chats
для хранения данных бота и связанных с ним чатов.
Выполните миграции:
php artisan vendor:publish --tag="telegraph-migrations"
php artisan migrate
Опубликуйте конфигурационный файл. Эта команда создаст файл config/telegraph.php
, где будут храниться все настройки вашего бота:
php artisan vendor:publish --tag="telegraph-config"
Добавьте токен в .env.
Откройте файл .env
в корне вашего проекта:
nano .env
Добавьте в него токен, который вы получили от BotFather:
TELEGRAPH_BOT_TOKEN=ваш_токен
Изменение разрешений и конфиденциальности бота
Прежде чем наш бот сможет отправлять и, что более важно, получать сообщения в группах, необходимо изменить некоторые его настройки через @BotFather
.
-
Дайте боту разрешение присоединяться к группам Telegram. Отправьте команду
/setjoingroups
в чат с@BotFather
. Он спросит, для какого бота вы хотите изменить настройку. Выберите своего бота из списка и нажмите «Enable». - Отключите режим приватности — это ключевой момент. По умолчанию бот, добавленный в группу, видит только те сообщения, которые начинаются с символа
/
или являются прямым ответом на его сообщения. Чтобы наш бот мог читать все сообщения в чате и реагировать на них, режим приватности нужно отключить. Отправьте команду/setprivacy
тому же@BotFather
, выберите нужного бота и измените его статус на «Disabled».
Регистрация бота в Telegraph
Теперь нам нужно «познакомить» пакет Telegraph с нашим ботом и чатом, в который мы будем отправлять сообщения.
Чтобы зарегистрировать нового бота в приложении, Telegraph предоставляет удобный интерактивный мастер. Запустите его:
php artisan telegraph:new-bot
Эта команда запускает мастер, который проведет вас через процесс создания бота. Во время настройки у вас будет возможность:
- создать нового бота;
- добавить токен бота;
- ввести имя бота (опционально);
- добавить новый чат с его ID;
- настроить вебхук для бота.
Этот метод позволяет быстро зарегистрировать бота прямо из командной строки.
Регистрация чата в Telegraph
Чтобы отправлять сообщения в конкретный чат, Telegraph должен знать его уникальный идентификатор (chat_id
). Чтобы его узнать, сначала отправьте любое сообщение своему боту. Затем откройте в браузере следующую ссылку, подставив свой токен:
https://api.telegram.org/bot<ВАШ_ТОКЕН>/getUpdates
Вы увидите JSON-ответ, в котором легко найдете объект chat
, а внутри него — поле id
. Скопируйте это числовое значение.
Чтобы чат стал известен Telegraph, его нужно зарегистрировать:
-
Введите команду:
php artisan telegraph:new-chat
-
Укажите ID чата Telegram.
-
При желании укажите название для чата.
Чат успешно добавлен в базу данных.
Тестирование отправки сообщений
Как только ваш бот и хотя бы один чат настроены, вы можете отправлять сообщения с помощью пакета Telegraph.
Отправка простого сообщения
Откройте файл routes/web.php
:
nano routes/web.php
Добавьте в него код:
use DefStudio\Telegraph\Models\TelegraphChat;
Route::get('/send-telegram', function () {
$chat = TelegraphChat::where('chat_id', 'id_вашего_чата')->first();
$chat->message('Привет!')->send();
return response()->json(['Сообщение успешно отправлено'], 200);
});
Укажите id вашего чата в коде.
Запустите сервер для теста:
php artisan serve
Теперь при переходе по адресу http://127.0.0.1:8000/send-telegram
бот должен отправлять сообщения в чат Telegram.
curl -I http://127.0.0.1:8000/send-telegram
Форматирование текста сообщения
В Telegraph можно отправлять сообщения в форматах Markdown и HTML:
$chat->markdown("*Привет! Это сообщение формата...*\n\n_Markdown!_")->send();
$chat->html("<strong>А это сообщение</strong>\n\nHTML!")->send();
Особенно полезно для высоконагруженных ботов — отправлять сообщения через систему очередей Laravel, чтобы не задерживать выполнение основного кода. Для организации взаимодействия с Telegraph через систему очередей можно использовать метод dispatch()
:
Telegraph::message('Привет')->dispatch('имя_вашей_очереди');
Отправка сообщения без звука:
$chat->message("тссс🤫, тихое сообщение")->silent()->send();
Бот успешно отправил сообщения.
Более подробную информацию обо всех возможностях Telegraph вы всегда можете найти в документации.
Настройка полноценного веб-сервера Nginx
Встроенный сервер, запускаемый через php artisan serve
, отлично подходит для разработки, но для реальной работы нужен полноценный веб-сервер.
Nginx на Ubuntu традиционно использует /etc/nginx/sites-available
и /etc/nginx/sites-enabled
— именно здесь мы будем хранить конфигурацию сайта и управлять включением или отключением виртуальных хостов.
Откройте файл конфигурации Nginx для проекта:
nano /etc/nginx/sites-available/telegram-bot
Вставьте в него:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/telegram-bot/public; # <-- если проект в другом месте, замените путь
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
try_files $uri =404;
access_log off;
expires max;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# обычно на Ubuntu сокет в /run/php/
fastcgi_pass unix:/run/php/php8.2-fpm.sock; # <-- проверьте версию PHP
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
access_log /var/log/nginx/telegram-bot.access.log;
error_log /var/log/nginx/telegram-bot.error.log;
}
Внимательно проверьте корректность путей в root
и fastcgi_pass
. Аргумент root
должен указывать на папку public
в проекте, а fastcgi_pass
— на сокет PHP.
Проверка наличия сокета:
ls -l /run/php/
Вы должны увидеть файл php8.2-fpm.sock
.
Создайте симлинк:
sudo ln -s /etc/nginx/sites-available/telegram-bot /etc/nginx/sites-enabled/telegram-bot
Обычно в /etc/nginx/sites-enabled
присутствует стандартный default
, и в нем тоже указан default_server
. Удалите симлинк, чтобы не было дубликата:
sudo rm /etc/nginx/sites-enabled/default
Проверьте конфигурацию:
sudo nginx -t
Если в выводе вы видите syntax is ok
и test is successful
, перезагрузите Nginx:
sudo systemctl reload nginx
Измените владельца и группу для следующих директорий, чтобы они корректно обрабатывались веб-сервером Nginx:
chown -R www-data:www-data /var/www/telegram-bot/storage/framework/views/
chown -R www-data:www-data /var/www/telegram-bot/storage/logs/
chown -R www-data:www-data /var/www/telegram-bot/public/
chown -R www-data:www-data /var/www/telegram-bot/database/
Получение updates от Telegram в Laravel
Вам нужно определить способ, которым Telegram будет отправлять обновления вашему боту.
Обычно в продакшене рекомендуется использовать вебхуки. Это позволяет получать обновления в реальном времени (сообщения, команды и т. д.) по URL вашего приложения без постоянного опроса API. Telegram будет отправлять HTTP-запросы на указанный вами вебхук каждый раз, когда происходит событие, связанное с вашим ботом — например, когда пользователь отправляет сообщение.
Сначала напишем свой обработчик вебхука.
Создание обработчика вебхука
Создайте папку app/Handlers
:
mkdir app/Handlers
Создайте в папке Handlers
файл CustomWebhookHandler.php
:
nano app/Handlers/CustomWebhookHandler.php
Вставьте в него код:
<?php
namespace App\Handlers;
use Illuminate\Support\Stringable;
use DefStudio\Telegraph\Handlers\WebhookHandler;
class CustomWebhookHandler extends WebhookHandler
{
protected function handleChatMessage(Stringable $text): void
{
// полученное сообщение отправляется обратно в чат
$this->chat->html("Вы написали: $text")->send();
}
}
Нам также нужно указать обработчик для кастомизации логики обработки входящих запросов.
Откройте config/telegraph.php
:
nano config/telegraph.php
Найдите параметр webhook
:
Внесите изменения:
'webhook' => [
'handler' => App\Handlers\CustomWebhookHandler::class,
],
Теперь при работе бота каждое простое сообщение, отправленное в Telegram, будет обрабатываться методом handleChatMessage
в вашем обработчике CustomWebhookHandler
, и бот будет отвечать сообщением в чат.
По умолчанию вебхуки могут обрабатывать входящие запросы только из известных им чатов — тех, что хранятся в базе данных в виде моделей TelegraphChat
. Все остальные запросы отклоняются.
Чтобы разрешить обработку сообщений из неизвестных чатов, отредактируйте config/telegraph.php
следующим образом:
'security' => [
/*
* if enabled, allows callback queries from unregistered chats
*/
'allow_callback_queries_from_unknown_chats' => true,
/*
* if enabled, allows messages and commands from unregistered chats
*/
'allow_messages_from_unknown_chats' => true,
/*
* if enabled, store unknown chats as new TelegraphChat models
*/
'store_unknown_chats_in_db' => true,
],
Установка вебхука
Поскольку мы работаем в локальной среде, необходимо предоставить доступ к нашему локальному Laravel-серверу из интернета по HTTPS, так как Telegram не поддерживает HTTP.
Для отладки во время разработки можно воспользоваться такими сервисами, как ngrok
или VK Tunnel
, которые пробрасывают локальный сервер на временный домен в интернете. Порт по умолчанию для работы с Laravel — 8000
. Это простой и безопасный способ дать Telegram публичный URL к вашему локальному Nginx.
В продакшене рекомендую использовать стабильный VDS c доменом в Timeweb Cloud. Клиентам предоставляется готовая инфраструктура, постоянный публичный IP и SSL-поддержка, что избавляет от многих проблем с вебхуками. Доступны разные регионы для сервера: РФ, Казахстан, Нидерланды и др.
Способ 1. Использование своего домена (рекомендуется для продакшена)
Переход на собственный домен — ключевой этап для запуска вашего бота в полноценную эксплуатацию. Это обеспечит стабильность работы и доверие пользователей. В отличие от временных тоннелей домен не изменяется и остается постоянным, пока он действителен.
Купите домен, например, у Timeweb Cloud.
Создайте A-запись, указывающую на IP-адрес вашего сервера.
Установите бесплатный SSL-сертификат с помощью Certbot. Он автоматически обновит конфигурацию nginx.
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d ваш_домен.ru
sudo systemctl reload nginx
Обновите .env
, указав новую ссылку:
nano .env
Измените:
APP_URL=https://ваш_домен.ru
Выполните команду:
php artisan telegraph:set-webhook
Теперь бот готов к работе.
Способ 2. Через Ngrok
Чтобы установить ngrok
на Linux зарегестрируйте аккаунт на ngrok и следуйте этой короткой инструкции.
Для корректной работы ngrok
рекомендуем использовать сервер в Нидерландах или Германии.
После установки ngrok
выполните:
ngrok http 80
В терминале должен отобразиться URL.
Если вы увидите подобный вывод в терминале, значит ngrok
работает.
Скопируйте ссылку на тоннель (выделена на скриншоте).
Обновите .env
, указав новую ссылку. Откройте файл:
nano .env
Измените:
APP_URL=ваша-https-ссылка-тоннеля
Выполните команду:
php artisan telegraph:set-webhook
Теперь бот готов к работе.
Способ 3. Через VK tunnel
VK tunnel
, как и ngrok
, позволяет пробрасывать локальный сервер на временный домен. Если у вас возникли проблемы с доступом к ngrok
— попробуйте VK tunnel
.
Установите пакетный менеджер npm
:
sudo apt install npm
Установите пакет vk-tunnel
:
npm install @vkontakte/vk-tunnel -g
Запустите тоннель:
vk-tunnel --insecure=1 --http-protocol=http --ws-protocol=ws --host=localhost --port=80 --timeout=5000
При первом запуске вас попросят авторизоваться. Для этого скопируйте ссылку из терминала и перейдите по ней в браузере, где вы авторизованы в своем аккаунте ВКонтакте.
Скопируйте ссылку на тоннель из строки https
.
Обновите .env
, указав новую ссылку:
nano .env
Измените:
APP_URL=ваша-https-ссылка-тоннеля
Выполните команду:
php artisan telegraph:set-webhook
Теперь бот готов к работе.
Тестирование бота
Просто отправьте любое сообщение вашему боту в Telegram. Если все шаги были выполнены верно, он должен немедленно ответить вам.
При возникновении ошибок обратите внимание, на каком этапе они появляются. Проверьте логи в терминале с туннелем и локальным сервером. Ошибки Laravel можно посмотреть в файле storage/logs/laravel.log
.
Поддержка команд
Давайте научим нашего бота реагировать на конкретные команды, например /start
, и показывать интерактивные кнопки.
Чтобы бот реагировал на команду, нужно прописать ее логику в CustomWebhookHandler
.
Откройте обработчик app/Handlers/CustomWebhookHandler.php
и приведите его к следующему виду:
nano app/Handlers/CustomWebhookHandler.php
Внесите изменения:
<?php
namespace App\Handlers;
use DefStudio\Telegraph\Keyboard\Button;
use DefStudio\Telegraph\Keyboard\Keyboard;
use Illuminate\Support\Stringable;
use DefStudio\Telegraph\Handlers\WebhookHandler;
class CustomWebhookHandler extends WebhookHandler
{
protected function handleChatMessage(Stringable $text): void
{
$this->chat->markdown("Вы написали: $text")->send();
}
/**
* @var string[] Список команд, которые можно вызывать текстом.
*/
protected array $allowedCommands = [
'start',
'buttons',
'chatid', // команда из базового класса
];
/**
* Родительский метод для фильтрации команд.
*/
protected function handleCommand(Stringable $text): void
{
[$command, $parameter] = $this->parseCommand($text);
// если пришедшей команды нет в нашем белом списке,
// то сразу отправляем на обработку как неизвестную команду
if (!in_array($command, $this->allowedCommands)) {
$this->handleUnknownCommand($text);
return;
}
// иначе вызываем обработчик команд из родителя
parent::handleCommand($text);
}
public function start(): void
{
$this->chat->markdown("*Привет!* Я бот, работающий на Laravel!")->send();
}
public function buttons(): void
{
$this->chat->message('Это сообщение с кнопками. Выбери действие:')
->keyboard(Keyboard::make()->buttons([
Button::make("🗑️ Удалить сообщение")->action("delete"),
Button::make("📖 Поделиться мудростью")->action("read"),
Button::make("👀 Открыть ссылку")->url('https://timeweb.cloud/'),
])->chunk(2))->send();
}
/**
* Обрабатывает нажатие на кнопку с action("delete")
*/
public function delete(): void
{
$this->reply('Сообщение удалено');
$this->chat->deleteMessage($this->messageId)->send();
}
/**
* Обрабатывает нажатие на кнопку с action("read")
*/
public function read(): void
{
$wisdomText = "40% проблем с производительностью решаются оптимизацией кода. Оставшиеся 60% решаются переездом на *Timeweb Cloud*. Будь разумнее — начни с 60%.";
$this->reply('Мудрость явлена!', true);
$this->chat->edit($this->messageId)->markdown($wisdomText)->send();
}
}
Мы добавили команды /start
и /buttons
:
-
/start
выводит приветственное сообщение. -
/buttons
открывает интерфейс с кнопками, к которым можно прикрепить поведение.
Нажатие на кнопки будет вызывать соответствующие методы (delete_message
, share_wisdom
), а кнопка со ссылкой просто откроет сайт в браузере.
Проверим работу кнопки «Поделиться мудростью»:
Кнопка успешно отработала.
Разместите бота на собственном сервере
Заключение
В этом руководстве был продемонстрирован полный цикл создания Telegram-бота с использованием фреймворка Laravel и пакета Telegraph. Вы получили рабочую основу, которая позволяет не только отправлять сообщения, но и обрабатывать команды, а также создавать интерактивные клавиатуры. Это базовые элементы для построения функциональных ботов, способных решать реальные задачи: от автоматизации рутинных операций до создания каналов взаимодействия с пользователями.
Использование домена значительно облегчает обработку сообщений из Telegram. Для стабильной работы бота в производственной среде требуется надежный сервер, доступный 24/7 и имеющий постоянный SSL-сертификат для корректной работы вебхуков. С этой задачей эффективно справляются облачные VDS, такие как Timeweb Cloud. Вам предоставляется готовая к работе инфраструктура, которая избавляет от необходимости сложной настройки окружения и позволяет развернуть бота в несколько шагов, обеспечив его стабильность и производительность.