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

v0.1.1-beta 2026-01-16 21:00 UTC

This package is auto-updated.

Last update: 2026-01-16 21:06:16 UTC


README

Proto Brick

Latest Stable Version PHP Version API Layer License Telegram Chat

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 tdlib binary 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_hash and resolves @usernames or IDs via 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.

  1. Download the new .json schema file (e.g., from here).
  2. Ensure the filename contains the version number (e.g., TL_telegram_v220.json).
  3. Place the file in the schema/ directory (you can keep the old ones; the builder automatically picks the highest version).
  4. 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.