Routing
Routing in TGbot Laravel allows you to define handlers for various types of Telegram updates. The API is very similar to standard Laravel routing, making it intuitive.
Basic Concepts
Section titled “Basic Concepts”TelegramRouter Facade
Section titled “TelegramRouter Facade”All routes are registered through the TelegramRouter facade:
use HybridGram\Facades\TelegramRouter;
TelegramRouter::onCommand('/start', function(CommandData $data) { // Handle /start command});Handler Structure
Section titled “Handler Structure”Route handlers receive a data object (e.g., CommandData, TextMessageData) that contains:
$data->update— full Update object from Telegram$data->botId— ID of the bot for which the route was triggered$data->getChat()— Chat object$data->getUser()— User object- Additional properties depending on the data type
Route Types
Section titled “Route Types”Commands
Section titled “Commands”Handling commands starting with /:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\RouteData\CommandData;
// Simple commandTelegramRouter::onCommand('/start', function(CommandData $data) { $telegram = app(\HybridGram\Telegram\TelegramBotApi::class); $telegram->sendMessage($data->getChat()->id, 'Hello!');});
// Command with parametersTelegramRouter::onCommand('/help', function(CommandData $data) { // $data->commandParams contains array of arguments after the command $params = $data->arguments; // ...});
// Command for specific botTelegramRouter::forBot('main')->onCommand('/start', function(CommandData $data) { // ...});Messages
Section titled “Messages”Handling text messages:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\RouteData\TextMessageData;
// All messagesTelegramRouter::onTextMessage(function(TextMessageData $data) { $message = $data->message; // ...});
// Messages by patternTelegramRouter::onTextMessage(function(TextMessageData $data) { // ...}, '*', 'hello'); // Pattern to check text
// Custom check via closureTelegramRouter::onTextMessage(function(TextMessageData $data) { // ...}, '*', function(TextMessageData $data) { return str_contains($data->message, 'hello');});Callback Query
Section titled “Callback Query”Handling inline button presses:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\RouteData\CallbackQueryData;
// All callback queriesTelegramRouter::onCallbackQuery(function(CallbackQueryData $data) { $callbackQuery = $data->callbackQuery; $action = $data->action; $params = $data->params; // ...});
// Callback query by pattern (e.g., action="menu:home")TelegramRouter::onCallbackQuery(function(CallbackQueryData $data) { // ...}, '*', 'menu:*');
// With query parameter checkTelegramRouter::onCallbackQuery(function(CallbackQueryData $data) { // ...}, '*', '*', ['category' => 'products']); // only if category=products existsWorking with Multiple Bots
Section titled “Working with Multiple Bots”If you have multiple bots, you can specify a specific bot:
// For specific botTelegramRouter::forBot('main')->onCommand('/start', function(CommandData $data) { // ...});
// For all bots (default)TelegramRouter::onCommand('/start', function(CommandData $data) { // ...});Filtering by Chat Type
Section titled “Filtering by Chat Type”Routes can be limited to specific chat types (private, groups, supergroups, channels).
Single Chat Type
Section titled “Single Chat Type”Use the chatType() method to specify a single chat type:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\ChatType;
// Route only for private chats (default for most types)TelegramRouter::forBot('main') ->chatType(ChatType::PRIVATE) ->onCommand('/start', function(CommandData $data) { // Handle only in private chats });
// Route only for groupsTelegramRouter::forBot('main') ->chatType(ChatType::GROUP) ->onTextMessage(function(\HybridGram\Core\Routing\RouteData\TextMessageData $data) { // Handle only in groups });Multiple Chat Types
Section titled “Multiple Chat Types”Use the chatTypes() method to specify multiple chat types:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\ChatType;
// Route works in private chats and groupsTelegramRouter::forBot('main') ->chatTypes([ChatType::PRIVATE, ChatType::GROUP]) ->onCommand('/help', function(CommandData $data) { // Handle in private chats and groups });
// Route works in all chat typesTelegramRouter::forBot('main') ->chatTypes(null) // or don't specify for group events ->onMyChatMember(function(ChatMemberUpdatedData $data) { // Handle in all chat types });Smart Defaults
Section titled “Smart Defaults”The system automatically sets reasonable defaults depending on route type:
Routes that work in all chat types by default:
onMyChatMember()— bot status changesonChatMember()— member status changesonNewChatTitle()— chat title changesonNewChatPhoto()— chat photo changesonDeleteChatPhoto()— chat photo deletiononPinnedMessage()— message pinningonForumTopicEvent()— forum topic eventsonGeneralForumTopicEvent()— general topic eventsonMessageAutoDeleteTimerChanged()— auto-delete timer changesonBoostAdded()— boost added
Other routes work only in private chats by default:
onCommand()— commandsonMessage()— messagesonCallbackQuery()— callback queries- And others…
// Works in all chat types (default for MY_CHAT_MEMBER)TelegramRouter::onMyChatMember(function(ChatMemberUpdatedData $data) { // Handle bot added to group/channel});
// Works only in private chats (default for COMMAND)TelegramRouter::onCommand('/start', function(CommandData $data) { // Handle command});
// Explicitly specify multiple types for commandTelegramRouter::forBot('main') ->chatTypes([ChatType::PRIVATE, ChatType::GROUP]) ->onCommand('/admin', function(CommandData $data) { // Command works in private chats and groups });Chat Types
Section titled “Chat Types”Available chat types:
use HybridGram\Core\Routing\ChatType;
ChatType::PRIVATE // Private chatsChatType::GROUP // GroupsChatType::SUPERGROUP // SupergroupsChatType::CHANNEL // ChannelsRoute Grouping
Section titled “Route Grouping”You can group routes with common attributes, including chat type:
use HybridGram\Facades\TelegramRouter;use HybridGram\Core\Routing\ChatType;
TelegramRouter::group([ 'for_bot' => 'main', 'chat_type' => ChatType::GROUP, // Single type 'middlewares' => [AuthTelegramRouteMiddleware::class],], function($router) { $router->onCommand('/admin', function(CommandData $data) { // ... });});
// Or multiple typesTelegramRouter::group([ 'for_bot' => 'main', 'chat_type' => [ChatType::PRIVATE, ChatType::GROUP], // Array of types], function($router) { $router->onTextMessage(function(TextMessageData $data) { // ... });});Patterns and Filtering
Section titled “Patterns and Filtering”String Patterns
Section titled “String Patterns”Many route types support string patterns using *:
// Command with parametersTelegramRouter::onCommand('/user:*', function(CommandData $data) { $userId = $data->commandParams[0] ?? null; // ...});
// Callback queryTelegramRouter::onCallbackQuery(function(CallbackQueryData $data) { // $data->action will contain "menu:products" // $data->params will contain ['category' => 'electronics']}, '*', 'menu:*', ['category' => null]); // category must be presentClosure Patterns
Section titled “Closure Patterns”For more complex logic, use closures:
TelegramRouter::onTextMessage(function(TextMessageData $data) { // ...}, '*', function(TextMessageData $data) { // Return true if route should trigger return $data->message->text !== null && strlen($data->message->text) > 100;});Additional Route Types
Section titled “Additional Route Types”The package supports many other update types:
onPhoto— photosonDocument— documentsonLocation— geolocationonContact— contactsonPoll— pollsonInlineQuery— inline queriesonAny— any updates- And much more
See the corresponding sections for details on each type.
Fallback Routes
Section titled “Fallback Routes”A route that triggers when no suitable handler is found:
TelegramRouter::onFallback(function(FallbackData $data) { $telegram = app(\HybridGram\Telegram\TelegramBotApi::class); $telegram->sendMessage($data->getChat()->id, 'Command not recognized');});In development mode (app()->isLocal()) fallback automatically sends state information for debugging.
Alternative: PHP Attributes
Section titled “Alternative: PHP Attributes”If you prefer a more modern, attribute-based approach to routing, you can use PHP 8 attributes instead of the facade. This keeps route definitions close to your handler methods:
#[OnCommand('/start')]public function handleStart(CommandData $data): void { // Handle /start command}→ Learn about PHP Attributes Routing
What’s Next?
Section titled “What’s Next?”- Handling Commands — detailed work with commands
- Handling Messages — working with text messages
- Callback Query — handling button presses
- PHP Attributes Routing — modern attribute-based routing