Skip to content

Middleware

Middleware позволяет выполнять код до или после обработки обновления. Это полезно для авторизации, логирования, проверки состояний и других задач.

Все middleware должны реализовывать интерфейс TelegramRouteMiddlewareInterface:

use HybridGram\Core\Middleware\TelegramRouteMiddlewareInterface;
use Phptg\BotApi\Type\Update\Update;
class MyMiddleware implements TelegramRouteMiddlewareInterface
{
public function handle(Update $update, callable $next): mixed
{
// Код до обработки
$result = $next($update);
// Код после обработки
return $result;
}
}

Автоматически авторизует пользователя через Telegram Guard:

use HybridGram\Http\Middlewares\AuthTelegramRouteMiddleware;
TelegramRouter::forBot('main')
->onCommand('/profile', function(CommandData $data) {
// Пользователь уже авторизован
$user = Auth::user();
})
->middleware(AuthTelegramRouteMiddleware::class);

Устанавливает состояние после выполнения обработчика:

use HybridGram\Http\Middlewares\SetStateTelegramRouteMiddleware;
TelegramRouter::onCommand('/start', function(CommandData $data) {
// ...
})
->middleware(new SetStateTelegramRouteMiddleware(
newState: 'main_menu',
useUserState: false, // Использовать состояние чата (по умолчанию)
ttl: 3600, // Время жизни в секундах (опционально)
data: ['step' => 1] // Дополнительные данные (опционально)
));

Проверяет, находится ли чат/пользователь в определенном состоянии:

use HybridGram\Http\Middlewares\CheckStateTelegramRouteMiddleware;
TelegramRouter::onMessage(function(MessageData $data) {
// Этот роут сработает только если чат в состоянии 'awaiting_input'
})
->middleware(new CheckStateTelegramRouteMiddleware(
requiredStates: ['awaiting_input'],
useUserState: false, // Проверять состояние чата
exceptMode: false // false = только если В состоянии, true = только если НЕ в состоянии
));

Пример с исключением состояний:

// Роут сработает только если НЕ в состояниях 'processing' или 'awaiting'
TelegramRouter::onCommand('/cancel', function(CommandData $data) {
// ...
})
->middleware(new CheckStateTelegramRouteMiddleware(
requiredStates: ['processing', 'awaiting'],
exceptMode: true // Исключающий режим
));

Ограничивает частоту запросов от пользователя:

use HybridGram\Http\Middlewares\RateLimitTelegramRouteMiddleware;
TelegramRouter::onMessage(function(MessageData $data) {
// ...
})
->middleware(new RateLimitTelegramRouteMiddleware(
maxAttempts: 10,
decayMinutes: 1
));

Логирует все обновления:

use HybridGram\Http\Middlewares\LoggingTelegramRouteMiddleware;
TelegramRouter::onAny(function(AnyData $data) {
// ...
})
->middleware(LoggingTelegramRouteMiddleware::class);
TelegramRouter::onCommand('/admin', function(CommandData $data) {
// ...
})
->middleware(AuthTelegramRouteMiddleware::class);
TelegramRouter::onCommand('/admin', function(CommandData $data) {
// ...
})
->middleware([
AuthTelegramRouteMiddleware::class,
new RateLimitTelegramRouteMiddleware(maxAttempts: 5, decayMinutes: 1),
]);
TelegramRouter::group([
'botId' => 'main',
'middlewares' => [
AuthTelegramRouteMiddleware::class,
LoggingTelegramRouteMiddleware::class,
],
], function($router) {
$router->onCommand('/admin', function(CommandData $data) {
// Оба middleware применятся
});
$router->onCommand('/settings', function(CommandData $data) {
// Оба middleware применятся
});
});

Создание собственного Middleware

Section titled “Создание собственного Middleware”

Пример: Проверка прав администратора

Section titled “Пример: Проверка прав администратора”
<?php
namespace App\Telegram\Middleware;
use HybridGram\Core\Middleware\TelegramRouteMiddlewareInterface;
use HybridGram\Core\UpdateHelper;
use Phptg\BotApi\Type\Update\Update;
class AdminMiddleware implements TelegramRouteMiddlewareInterface
{
public function handle(Update $update, callable $next): mixed
{
$user = UpdateHelper::getUserFromUpdate($update);
if (!$user || !$this->isAdmin($user->id)) {
$telegram = app(\HybridGram\Telegram\TelegramBotApi::class);
$chat = UpdateHelper::getChatFromUpdate($update);
if ($chat) {
$telegram->sendMessage(
$chat->id,
'❌ У вас нет прав для выполнения этой команды'
);
}
return null; // Прервать выполнение
}
return $next($update);
}
private function isAdmin(int $userId): bool
{
// Ваша логика проверки
return in_array($userId, config('telegram.admins', []));
}
}

Использование:

use App\Telegram\Middleware\AdminMiddleware;
TelegramRouter::onCommand('/admin', function(CommandData $data) {
// Доступ только для администраторов
})
->middleware(AdminMiddleware::class);

Пример: Логирование с контекстом

Section titled “Пример: Логирование с контекстом”
<?php
namespace App\Telegram\Middleware;
use HybridGram\Core\Middleware\TelegramRouteMiddlewareInterface;
use HybridGram\Core\UpdateHelper;
use Phptg\BotApi\Type\Update\Update;
class RequestLoggingMiddleware implements TelegramRouteMiddlewareInterface
{
public function handle(Update $update, callable $next): mixed
{
$startTime = microtime(true);
$user = UpdateHelper::getUserFromUpdate($update);
$chat = UpdateHelper::getChatFromUpdate($update);
logger()->info('Telegram update received', [
'user_id' => $user?->id,
'chat_id' => $chat?->id,
'update_id' => $update->updateId,
]);
try {
$result = $next($update);
$duration = microtime(true) - $startTime;
logger()->info('Telegram update processed', [
'duration_ms' => round($duration * 1000, 2),
'success' => true,
]);
return $result;
} catch (\Throwable $e) {
logger()->error('Telegram update failed', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
throw $e;
}
}
}

Вы можете зарегистрировать глобальные middleware в TelegramServiceProvider:

// В методе boot() вашего ServiceProvider
public function boot(): void
{
$middlewareManager = app(\HybridGram\Core\Middleware\MiddlewareManager::class);
$middlewareManager->addGlobalMiddleware(
LoggingTelegramRouteMiddleware::class
);
}

Глобальные middleware применяются ко всем роутам.

Middleware выполняются в следующем порядке:

  1. Глобальные middleware (в порядке регистрации)
  2. Middleware из группы роутов
  3. Middleware конкретного роута

Каждый middleware может:

  • Пропустить выполнение (return $next($update))
  • Прервать выполнение (return null)
  • Изменить данные (передать модифицированный Update)