Middleware
Middleware permite que você execute código antes ou depois de processar uma atualização. Isso é útil para autorização, logging, verificação de estados e outras tarefas.
Conceitos Básicos
Seção intitulada “Conceitos Básicos”Interface de Middleware
Seção intitulada “Interface de Middleware”Todo middleware deve implementar a interface TelegramRouteMiddlewareInterface:
use HybridGram\Core\Middleware\TelegramRouteMiddlewareInterface;use Phptg\BotApi\Type\Update\Update;
class MyMiddleware implements TelegramRouteMiddlewareInterface{ public function handle(Update $update, \Closure $next): mixed { // Código antes de processar
$result = $next($update);
// Código depois de processar
return $result; }}Middleware Integrados
Seção intitulada “Middleware Integrados”AuthTelegramRouteMiddleware
Seção intitulada “AuthTelegramRouteMiddleware”Autoriza automaticamente usuários através do Telegram Guard:
use HybridGram\Http\Middlewares\AuthTelegramRouteMiddleware;
TelegramRouter::forBot('main') ->onCommand('/profile', function(CommandData $data) { // Usuário já está autorizado $user = Auth::user(); }) ->middleware(AuthTelegramRouteMiddleware::class);SetStateTelegramRouteMiddleware
Seção intitulada “SetStateTelegramRouteMiddleware”Define o estado após a execução do manipulador:
use HybridGram\Http\Middlewares\SetStateTelegramRouteMiddleware;
TelegramRouter::onCommand('/start', function(CommandData $data) { // ...})->middleware(new SetStateTelegramRouteMiddleware( newState: 'main_menu', useUserState: false, // Usar estado do chat (padrão) ttl: 3600, // Tempo de vida em segundos (opcional) data: ['step' => 1] // Dados adicionais (opcional)));CheckStateTelegramRouteMiddleware
Seção intitulada “CheckStateTelegramRouteMiddleware”Verifica se o chat/usuário está em um estado específico:
use HybridGram\Http\Middlewares\CheckStateTelegramRouteMiddleware;
TelegramRouter::onTextMessage(function(TextMessageData $data) { // Esta rota só é acionada se o chat estiver no estado 'awaiting_input'})->middleware(new CheckStateTelegramRouteMiddleware( requiredStates: ['awaiting_input'], useUserState: false, // Verificar estado do chat exceptMode: false // false = apenas se EM estado, true = apenas se NÃO em estado));Exemplo com exclusão de estado:
// Rota acionada apenas se NÃO estiver nos estados 'processing' ou 'awaiting'TelegramRouter::onCommand('/cancel', function(CommandData $data) { // ...})->middleware(new CheckStateTelegramRouteMiddleware( requiredStates: ['processing', 'awaiting'], exceptMode: true // Modo de exclusão));RateLimitTelegramRouteMiddleware
Seção intitulada “RateLimitTelegramRouteMiddleware”Limita a frequência de requisições do usuário:
use HybridGram\Http\Middlewares\RateLimitTelegramRouteMiddleware;
TelegramRouter::onTextMessage(function(TextMessageData $data) { // ...})->middleware(new RateLimitTelegramRouteMiddleware( maxAttempts: 10, decayMinutes: 1));SetLocaleTelegramRouteMiddleware
Seção intitulada “SetLocaleTelegramRouteMiddleware”Define automaticamente a localidade do Laravel com base no idioma do usuário do Telegram:
use HybridGram\Http\Middlewares\SetLocaleTelegramRouteMiddleware;
TelegramRouter::forBot('main') ->onCommand('/start', function(CommandData $data) { // Localidade já está configurada com base no idioma do usuário return __('welcome_message'); }) ->middleware(new SetLocaleTelegramRouteMiddleware( supportedLocales: ['en', 'ru', 'uk', 'pt'], fallbackLocale: 'en' ));Resolução de Localidade Personalizada
Seção intitulada “Resolução de Localidade Personalizada”Você pode fornecer lógica personalizada para determinar a localidade usando o parâmetro userLocale:
Usando um Closure:
use HybridGram\Http\Middlewares\SetLocaleTelegramRouteMiddleware;use Phptg\BotApi\Type\Update\Update;
// Determinar localidade das configurações de usuário no banco de dadosTelegramRouter::forBot('main') ->onCommand('/start', function(CommandData $data) { return __('welcome_message'); }) ->middleware(new SetLocaleTelegramRouteMiddleware( supportedLocales: ['en', 'ru', 'uk', 'pt'], fallbackLocale: 'en', userLocale: function(Update $update): ?string { $user = UpdateHelper::getUserFromUpdate($update); if (!$user) { return null; }
// Buscar localidade do seu banco de dados $userModel = User::where('telegram_id', $user->id)->first(); return $userModel?->preferred_locale; } ));Usando uma string estática:
// Forçar uma localidade específica para todos os usuários nesta rotaTelegramRouter::onCommand('/en_only', function(CommandData $data) { // Sempre em inglês})->middleware(new SetLocaleTelegramRouteMiddleware( userLocale: 'en'));Usando Middleware
Seção intitulada “Usando Middleware”Para uma Rota Única
Seção intitulada “Para uma Rota Única”TelegramRouter::onCommand('/admin', function(CommandData $data) { // ...})->middleware(AuthTelegramRouteMiddleware::class);Múltiplos Middleware
Seção intitulada “Múltiplos Middleware”TelegramRouter::onCommand('/admin', function(CommandData $data) { // ...})->middleware([ AuthTelegramRouteMiddleware::class, new RateLimitTelegramRouteMiddleware(maxAttempts: 5, decayMinutes: 1),]);Em Grupos de Rotas
Seção intitulada “Em Grupos de Rotas”TelegramRouter::group([ 'botId' => 'main', 'middlewares' => [ AuthTelegramRouteMiddleware::class, LoggingTelegramRouteMiddleware::class, ],], function($router) { $router->onCommand('/admin', function(CommandData $data) { // Ambos os middleware serão aplicados });
$router->onCommand('/settings', function(CommandData $data) { // Ambos os middleware serão aplicados });});Criando Middleware Personalizado
Seção intitulada “Criando Middleware Personalizado”Exemplo: Verificação de Permissões de Administrador
Seção intitulada “Exemplo: Verificação de Permissões de Administrador”<?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, \Closure $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, '❌ Você não tem permissão para executar este comando' ); }
return null; // Parar execução }
return $next($update); }
private function isAdmin(int $userId): bool { // Sua lógica de validação return in_array($userId, config('telegram.admins', [])); }}Uso:
use App\Telegram\Middleware\AdminMiddleware;
TelegramRouter::onCommand('/admin', function(CommandData $data) { // Acesso apenas para administradores})->middleware(AdminMiddleware::class);Middleware Global
Seção intitulada “Middleware Global”Você pode registrar middleware global em TelegramServiceProvider:
// No método boot() do seu ServiceProviderpublic function boot(): void{ $middlewareManager = app(\HybridGram\Core\Middleware\MiddlewareManager::class);
$middlewareManager->addGlobalMiddleware( LoggingTelegramRouteMiddleware::class );}Middleware global se aplica a todas as rotas.
Ordem de Execução
Seção intitulada “Ordem de Execução”Middleware é executado na seguinte ordem:
- Middleware global (em ordem de registro)
- Middleware do grupo de rotas
- Middleware de rota específica
Cada middleware pode:
- Continuar execução (
return $next($update)) - Parar execução (
return null) - Modificar dados (passar Update modificado)
Próximos Passos
Seção intitulada “Próximos Passos”- Estados — gerenciando estados de chat e usuário
- Enviando Mensagens — trabalhando com TelegramBotApi