protobrick / mtproto-client
Modern async pure PHP client library for Telegram MTProto API
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/protobrick/mtproto-client
Requires
- php-64bit: >=8.2
- ext-json: *
- ext-zlib: *
- amphp/socket: ^2.3
- amphp/sync: ^2.3
- phpseclib/phpseclib: ^3.0
- psr/log: ^3.0
- revolt/event-loop: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.85
- phpunit/phpunit: ^11
- vlucas/phpdotenv: ^5.6
Suggests
- ext-bcmath: Install the bcmath extension to speed up authorization
- ext-gmp: Install the gmp extension to speed up authorization
- ext-mbstring: Recommended for correct handling of UTF-8 strings in Telegram messages
- ext-openssl: Speeds up crypto operations (AES/RSA) significantly
- ext-pcntl: Allows graceful shutdown using SIGINT/SIGTERM signals
- ext-uv: Drastically reduces CPU usage and improves concurrency. Enables true async file I/O
This package is auto-updated.
Last update: 2026-01-16 21:06:16 UTC
README
Proto Brick is just starting its journey. Your stars ⭐️ are crucial for the project's visibility!
Proto Brick
Modern async pure PHP client library for Telegram MTProto. Build userbots with direct API access — no TDLib dependencies.
Note
🚧 Work in Progress: This library is currently under active development. Features are being added rapidly, and breaking changes may occur before the v1.0 release.
🚀Features
- Full Async: Built on top of AMPHP and Revolt for high-performance non-blocking I/O.
- Pure PHP Implementation: No requirement for the official
tdlibbinary extension. Works anywhere PHP runs. - Strictly Typed: 100% of the API is auto-generated from the official TL-Schema.
- Direct API Access: 1:1 mapping of Telegram API methods (e.g.,
$client->messages->sendMessage). - Smart Peer Management: Automatically handles
access_hashand resolves@usernamesorIDsvia local cache. - Advanced Logging: Native colorized console output with channel filtering, fully compatible with PSR-3
📋Requirements
- PHP 8.2+ (64-bit)
- Required Extensions:
ext-zlib,ext-json - Highly Recommended Extensions:
ext-gmp(Speeds up crypto/auth operations).ext-openssl(Speeds up crypto operations).ext-uv(Better event loop performance).
Installation
composer require "protobrick/mtproto-client:^0.1-beta"
Authentication
Interactive Login (CLI)
Run once to log in. It prompts for credentials (phone, code, 2FA) and saves the session locally.
<?php //auth.php require __DIR__ . '/vendor/autoload.php'; use ProtoBrick\MTProtoClient\Client; use ProtoBrick\MTProtoClient\Settings; // Get your api_id and api_hash from https://my.telegram.org $settings = new Settings( api_id: 12345, api_hash: 'your_api_hash' ); // Session files will be stored in 'session_name' folder $client = Client::create($settings, __DIR__ . '/session_name'); $auth = $client->login(); $client->logger->info("Logged in as {$auth->user->firstName}\n");
Custom Flow
If you need to handle login programmatically (e.g., from database, API, or custom input), pass callables
$auth = $client->login( phoneNumber: '+1234567890', codeProvider: fn() => readline("Code: "), // Or fetch from DB/API passwordProvider: fn() => readline("2FA: "), // Or fetch from DB/API signupProvider: fn() => [readline("Name: "), readline("Last Name: ")] );
Calling API Methods
Use this for simple scripts (e.g., cron jobs) where you need to perform an action and exit.
<?php require __DIR__ . '/vendor/autoload.php'; use ProtoBrick\MTProtoClient\Client; use ProtoBrick\MTProtoClient\Settings; $settings = new Settings(api_id: 12345, api_hash: 'hash'); $client = Client::create($settings, __DIR__. '/session_name'); $client->channels->joinChannel(channel: "@ProtoBrickChat"); $client->messages->sendMessage( peer: "@ProtoBrickChat", //auto-resolve peer message: 'Hello from ProtoBrick!' );
Handling Updates
Use the Event Loop to build bots or tools that react to events in real-time.
<?php require __DIR__ . '/vendor/autoload.php'; use ProtoBrick\MTProtoClient\Client; use ProtoBrick\MTProtoClient\Settings; use ProtoBrick\MTProtoClient\Event\MessageContext; use ProtoBrick\MTProtoClient\Event\ServiceMessageContext; // Import specific TL types if you need raw checks use ProtoBrick\MTProtoClient\Generated\Types\Base\MessageActionChatCreate; use ProtoBrick\MTProtoClient\Generated\Types\Base\MessageMediaPhoto; use ProtoBrick\MTProtoClient\Generated\Types\Base\UpdateUserTyping; use ProtoBrick\MTProtoClient\TL\TlObject; $settings = new Settings(api_id: 12345, api_hash: 'hash'); $client = Client::create($settings, __DIR__. '/session_name'); // Handle New Messages $client->onMessage(function (MessageContext $ctx) { // Ignore own messages if ($ctx->isOutgoing()) return; // High-level helpers // (See src/Event/MessageContext.php & AbstractMessageContext.php) if ($ctx->getText() === '/ping') { $ctx->reply("Pong! 🏓"); $ctx->react('👍'); return; } // Low-level access // Check for media types, via_bot_id, reply_markup, etc. directly if ($ctx->message->media instanceof MessageMediaPhoto) { echo "Received a photo with caption: " . $ctx->getText(); } }); // Handle Edited Messages $client->onMessageEdit(function (MessageContext $ctx) { echo "EDIT in chat {$ctx->getChatId()}: {$ctx->getText()}\n"; }); // Handle Service Messages (Joins, Leaves, Title Changes) $client->onServiceMessage(function (ServiceMessageContext $ctx) { // High-level helpers // (See src/Event/ServiceMessageContext.php & AbstractMessageContext.php) if ($ctx->isTitleChanged()) { echo "Chat {$ctx->getChatId()} renamed to: {$ctx->getNewTitle()}\n"; } // Low-level access // Handle specific actions that don't have wrappers yet if ($ctx->message->action instanceof MessageActionChatCreate) { echo "Group created with title: " . $ctx->message->action->title; } }); // Handle Raw Updates (Typing, Status, Read Receipts) $client->onUpdate(function (TlObject $update) { // Catches ALL updates flowing from the server if ($update instanceof UpdateUserTyping) { echo "User {$update->userId} is typing...\n"; } }); // Start the Event Loop (Blocks execution) $client->start();
Async vs Sync Execution
The client provides generated *Async methods for every API call.
1. Synchronous & Concurrent
Use synchronous calls for simple logic, and concurrent execution for performance.
use function Amp\Future\await; // 🐢 Synchronous (Blocking) // Execution stops here until the channel is joined. $client->channels->joinChannel('@ProtoBrickChat'); // 🚀 Concurrent (Parallel) // Send multiple requests at once. Total time = time of the slowest request. $futures = []; foreach (['@Chat1', '@Chat2', '@Chat3'] as $chat) { // Returns Amp\Future immediately without waiting $futures[] = $client->channels->joinChannelAsync($chat); } // Wait for ALL requests to complete await($futures); echo "Joined all chats!";
2. Fire & Forget
Use ignore() for tasks where you don't care about the result or errors.
// The code continues immediately, the request is sent in the background $client->messages->sendMessageAsync( peer: 'me', message: 'Background log entry', )->ignore();
Warning
ignore() pushes the task to the Event Loop.
- Short Scripts: If your script ends immediately (reaches the end of the file), the Event Loop stops, and the request will not be sent.
- Daemons/Bots: This works perfectly inside
$client->start()or long-running processes, as the loop keeps turning.
Advanced Configuration
You can customize the connection settings via the Settings object:
use ProtoBrick\MTProtoClient\Transport\TransportProtocol; $settings = new Settings( api_id: ..., api_hash: ..., server_address: '149.154.167.50', // Custom DC IP transport: TransportProtocol::PaddedIntermediate, // Obfuscation connect_timeout_seconds: 10 );
Architecture
Generated Code
The core of this library is generated automatically:
src/Generated/Api/*.php: Methods grouped by namespace (messages,users, etc.).src/Generated/Types/**/*.php: DTOs for every TL object (InputPeer,Message,User, etc.).
API Layer Updates (Schema)
You can regenerate the library API for a newer or older API layer yourself, without waiting for a release.
- Download the new
.jsonschema file (e.g., from here). - Ensure the filename contains the version number (e.g.,
TL_telegram_v220.json). - Place the file in the
schema/directory (you can keep the old ones; the builder automatically picks the highest version). - Run the builder:
php bin/build.php
Downgrading: To build using a specific schema file, pass the path as an argument:
php bin/build.php schema/TL_old_v199.json
⚠️ Disclaimer
This library is intended for personal automation and educational use. We are not responsible for any account limitations caused by misuse, spamming, or violating Telegram's Terms of Service. Please automate responsibly.
💬 Community & Support
ProtoBrick is a young library, and we are building a community of developers interested in MTProto.
- Telegram Chat: Join the Discussion — Ask questions, suggest features, or share your projects.
- GitHub Issues: Found a bug? Open an issue here.
- Stars: If you find this library useful, please give it a star ⭐️! It helps us grow and keeps the updates coming.
Contributions (PRs) are always welcome!
License
MIT License. See LICENSE for details.
