The Telegram Client
The Tueen\Telegram\Telegram class (conventionally instantiated as $bot) is the primary entry point and client facade of the tueen/telegram library. It provides a unified, strictly typed interface for sending Bot API requests, listening for updates, managing multi-step flows, and resolving contextual parameters.
🚀 1. Instantiation
You can initialize the client either directly with your bot token or via a pre-built Config object:
Basic Instantiation
use Tueen\Telegram\Telegram;
$bot = new Telegram('YOUR_BOT_TOKEN');Advanced Instantiation with ConfigBuilder
For production environments requiring custom timeouts, proxy connections, retry policies, or test servers:
use Tueen\Telegram\Telegram;
$config = Telegram::create('YOUR_BOT_TOKEN')
->withTimeout(30.0)
->withRetryCount(3)
->build();
$bot = new Telegram($config);For a full list of networking and runtime settings, see the Configuration Reference.
⚡ 2. The Three Primary Roles of $bot
In your application, the $bot instance serves three essential purposes:
1. Direct Bot API Client
You can invoke all Telegram Bot API methods dynamically with full IDE autocompletion and named arguments:
$bot->sendMessage(
chatId: 123456789,
text: 'Hello from tueen/telegram!'
);Learn more in Calling Methods & Types.
2. Update Router & Dispatcher
The client listens for incoming updates and dispatches them to closures, classes, or attribute controllers:
// Register a command route:
$bot->onCommand('start', function (Update $update, Telegram $bot) {
$bot->sendMessage(text: 'Welcome! How can I assist you today?');
});
// Run the bot via Webhook, Polling, or AutoMode:
$bot->run();Learn more in Update Routing & Attributes and Running Modes.
3. Contextual Entity Resolver (PHP 8.4 Property Hooks)
During update processing, $bot automatically tracks the active update and provides instant shortcuts to chat, user, and message identifiers via modern PHP 8.4 Property Hooks:
$chatId = $bot->chatId; // e.g. 123456789
$userId = $bot->userId; // e.g. 987654321
$message = $bot->message; // Current ?Message instanceTip: Legacy method calls such as
$bot->chatId()continue to work with a deprecation notice for full backward compatibility. Learn more in Update & Message Helpers.
💡 3. Client Best Practices
Here are the recommended patterns to keep in mind when working with the $bot instance:
1. Always Use PHP Named Arguments
Telegram Bot API methods accept many optional parameters. Named arguments protect your code against parameter order changes and enable Contextual Auto-Injection (where repetitive parameters like chatId are automatically resolved from the active update):
// ✅ RECOMMENDED: Order-independent, self-documenting, auto-injects chatId:
$bot->sendMessage(
text: 'Order confirmed successfully.',
parseMode: ParseMode::HTML
);
// ❌ AVOID: Fragile positional arguments with trailing nulls:
$bot->sendMessage(123456, 'Order confirmed successfully.', null, null, null, null, 'HTML');2. Reusing a Single Client Instance
Telegram is lightweight and designed to be created once. In modern frameworks (such as Laravel, Symfony, or Slim), register $bot as a singleton in your dependency injection container:
// Example: Registering as a singleton in a PSR-11 container:
$container->singleton(Telegram::class, function () {
return new Telegram(getenv('TELEGRAM_BOT_TOKEN'));
});3. Organizing Complex Bots with Controllers
For simple bots, defining routes with closures directly in your script is quick and convenient. As your application grows, organize your commands and actions into dedicated Controller classes:
// Register a dedicated controller class decorated with routing attributes:
$bot->registerController(OrderController::class);See Attribute-Driven Controllers for examples of using
#[OnCommand]and#[OnCallbackQuery].
🏛️ 4. Architecture & Decoupled Subsystems
Under the hood, Telegram is not a monolithic class holding all bot logic. Instead, it uses a modular composition architecture that delegates work to single-responsibility components:
When to Access Subsystems Directly:
Most of the time, you interact exclusively with the $bot facade. However, you can access underlying subsystems when building low-level extensions, worker queues, persistent daemons, or custom integrations:
use Tueen\Telegram\Telegram;
use Tueen\Telegram\Client\CurlHttpClient;
$bot = new Telegram('YOUR_BOT_TOKEN');
// 1. Pure HTTP client (useful for worker queue jobs that only call API methods without processing updates):
$client = $bot->client;
$me = $client->getMe();
// 2. Underlying router instance (inspect or manipulate route collections directly):
$router = $bot->router;
// 3. Flow state manager (for custom state stores or manual session manipulation):
$flowManager = $bot->flowManager;
// 4. Context parameter resolver (manual default binding or contextual entity inspection):
$context = $bot->context;
$activeChatId = $context->chatId;
// 5. Scoped Client for Persistent Worker Engines (FrankenPHP, RoadRunner, Swoole, Laravel Octane):
// Clones the client into a thread-safe, isolated instance with dedicated context per update:
$scopedBot = $bot->scoped($incomingUpdate);
// 6. PSR-11 Dependency Injection Container:
// Connect an external DI container (e.g. Laravel Container, PHP-DI, Symfony DI) for controller auto-wiring:
$bot->container = $myContainer;
// 7. Persistent HTTP Connection Pool Management:
// Check cached TCP/TLS keep-alive handles or flush them during worker maintenance:
$poolCount = CurlHttpClient::getPoolCount();
CurlHttpClient::closeAllHandles();🧭 5. Complete Method & Property Reference
Below is the comprehensive catalog of all constants, properties, and methods provided on the Telegram class, grouped by architectural responsibility. Every item features syntax-highlighted signatures, parameter types, default values, and status badges.
🏛️ Class Constants & Public Properties
public const string BOT_API_VERSIONstringConstantpublic const string API_VERSION = self::BOT_API_VERSIONpublic ?Update $update = null?UpdateProperty Hookprivate(set) ContextResolver $contextContextResolverAsymmetric Visibilityprivate(set) TelegramClient $clientTelegramClientAsymmetric Visibilityprivate(set) UpdateDispatcher $dispatcherUpdateDispatcherAsymmetric Visibilityprivate(set) Config $configConfigAsymmetric Visibilitypublic RunningModeInterface $runningModeRunningModeInterfaceProperty Hookpublic mixed $containermixedProperty Hookpublic FlowManager $flowManagerFlowManagerProperty Hookpublic Router $routerRouterProperty HookA. Initialization & Testing Factory
Telegram::create(string $botToken)Telegram::fake(array $responses = [], string $botToken = 'FAKE_BOT_TOKEN')new Telegram(string|Config $tokenOrConfig)TelegramConstructorB. Execution & Running Modes
run(mixed ...$handlers)mixedCanonicalautoRun(mixed ...$handlers)mixedAdaptiveuseAutoMode(?PollingMode $polling = null, ?WebhookMode $webhook = null, bool $autoDeleteWebhook = false, bool $dropPendingUpdatesOnDelete = false, ?callable $detector = null)staticsetRunningMode(RunningModeInterface $mode)staticpoll(int $timeout = 30, int $limit = 100, ?array $allowedUpdates = null)Generator<int, Update>StreamingC. Update Pipeline & Middleware
middleware(callable $middleware)staticCanonicaluse(callable $middleware)staticAliaspipe(MiddlewareInterface|Closure $middleware)staticOutboundonBeforeRequest(callable $callback)staticHookonAfterRequest(callable $callback)staticHookonError(callable $callback)staticHookonResponse(callable $callback)staticHookD. Exception & Error Handling
catch(string|callable $exceptionOrHandler, ?callable $handler = null)staticCanonicalonUpdateError(callable $handler)staticAliashandleUpdateException(\Throwable $e, Update $update)boolInternalE. Update Routing & Controllers
group(array|callable $attributesOrCallback, ?callable $callback = null)staticRoutingonCommand(string $command, mixed $handler, bool $priority = false)RouteonCallbackQuery(?string $pattern, mixed $handler, bool $priority = false)RouteonMessage(?string $pattern, mixed $handler, bool $priority = false)RouteonText(?string $pattern, mixed $handler, bool $priority = false)RouteAliasonInlineQuery(?string $pattern, mixed $handler, bool $priority = false)Routeon(UpdateType|string $type, mixed $handler, bool $priority = false)RouteonFallback(mixed $handler)staticFallbackregisterController(string|object $controller)staticrouter()Routerhandle(mixed ...$handlers)staticinvokeHandler(mixed $handler, Update $update)mixedDispatcherF. Multi-Step Conversational Flows
flow(int|string|null $chatId = null, ?int $userId = null, ?Update $update = null)FlowSessionstartFlow(string $flowClass, ?Update $update = null, string $initialStep = 'start', array $initialData = [])FlowhasActiveFlow(int|string|null $chatId = null, ?int $userId = null, ?Update $update = null)boolgetActiveFlow(int|string|null $chatId = null, ?int $userId = null, ?Update $update = null)?FlowgetActiveFlowClass(int|string|null $chatId = null, ?int $userId = null, ?Update $update = null)?stringflowBack(int|string|null $chatId = null, ?int $userId = null, ?string $replyMessage = null, ?Update $update = null)boolcancelFlow(int|string|null $chatId = null, ?int $userId = null, ?string $replyMessage = 'Operation cancelled.', ?Update $update = null)boolfinishFlow(int|string|null $chatId = null, ?int $userId = null, ?Update $update = null)boolflowManager()FlowManagersetFlowStore(StateStoreInterface $store)staticsetRootFlow(?string $flowClass)staticG. Contextual Accessors & Property Hooks
$bot->chatId?intProperty Hook$bot->userId?intProperty Hook$bot->messageId?intProperty Hook$bot->businessConnectionId?stringProperty Hook$bot->messageThreadId?intProperty Hook$bot->inlineMessageId?stringProperty Hook$bot->callbackQueryId?stringProperty Hook$bot->inlineQueryId?stringProperty Hook$bot->shippingQueryId?stringProperty Hook$bot->preCheckoutQueryId?stringProperty Hook$bot->directMessagesTopicId?intProperty Hook$bot->guestQueryId?stringProperty Hook$bot->chat?ChatProperty Hook$bot->user?UserProperty Hook$bot->message?MessageProperty Hookreply(string|Text $text, mixed ...$args)mixedShortcutreplyChunked(string|Text $text, int $chunkSize = 4096, mixed ...$args)list<mixed>ChunkingsendMessageChunked(string|Text $text, int $chunkSize = 4096, int|string|null $chatId = null, mixed ...$args)list<mixed>ChunkingbindDefault(string $param, callable $resolver)staticH. Bot API Method Calls & File Operations
$bot->sendMessage(mixed ...$args)mixedDynamicsend(Method $method, ?Closure $uploadProgress = null, ?Closure $downloadProgress = null, ?RequestOptions $options = null)mixeddownloadFile(mixed $file, mixed $destination, ?callable $progress = null)BooleanResult|ErrorparseUpdate(string|array $payload)UpdateI. Underlying Subsystems & Dependency Injection
$bot->clientTelegramClientProperty$bot->dispatcherUpdateDispatcherProperty$bot->contextContextResolverPropertysetContainer(mixed $container)static$bot->containermixedProperty Hook$bot->flowManagerFlowManagerProperty Hook$bot->routerRouterProperty Hookscoped(?Update $update = null)staticConcurrency