TelegramPHP Documentation

Calling the API

Every Bot API method is a real method on the client, named exactly as Telegram names it, taking exactly the fields Telegram documents. Required fields are positional, in the order the documentation lists them; everything else is a named argument.

$telegram->sendMessage($chatId, 'Deploying now');

$telegram->sendMessage($chatId, '<b>Deploying now</b>',
    parse_mode: 'HTML',
    disable_notification: true,
    reply_parameters: ['message_id' => $message->message_id],
);

Because the arguments are named rather than a single options array, an editor completes them, a typo is a fatal error rather than a field Telegram silently ignores, and the docblock on each method is the Bot API's own description of what it does.

Promises

Nothing blocks. Every call returns a React\Promise\PromiseInterface that resolves with the result already turned into parts:

use Telegram\Parts\Message;

$telegram->sendMessage($chatId, 'hello')->then(function (Message $sent) {
    echo 'sent as message ', $sent->message_id, PHP_EOL;
});

Chain calls rather than nesting them, and always handle the rejection - a promise whose failure nobody handles is a bug that will not announce itself:

$telegram->sendMessage($chatId, 'working on it')
    ->then(fn (Message $sent) => $telegram->pinChatMessage($chatId, $sent->message_id))
    ->then(
        fn () => print("pinned\n"),
        fn (Throwable $e) => print("failed: {$e->getMessage()}\n"),
    );

See Handling errors for what those rejections are.

Results

What a call resolves with follows what the Bot API says it returns:

Telegram says You get
Message a Telegram\Parts\Message
Array of Update a Discord\Helpers\Collection of Update parts
True true
String , Integer the scalar
Message or True whichever actually came back

That last row is the interesting one. editMessageText answers with the edited message when the bot can see it, and with true when the message is an inline one it cannot read back. The client hydrates whichever shape arrived, so a handler can simply check:

$telegram->editMessageText('done', chat_id: $chatId, message_id: $id)
    ->then(function (Message|bool $result) {
        if ($result instanceof Message) {
            // the edited message
        }
    });

Awaiting a result

In a script that is not itself a bot - a one-off task, a test - React\Async\await() turns a promise into a return value:

use function React\Async\await;

$me = await($telegram->getMe());
echo $me->username;

Never use it inside an event handler of a running bot: it runs the loop re-entrantly and will deadlock against the call you are already inside.

Files

Any field the documentation types as InputFile or String takes either. Pass a string to reuse a file_id or point Telegram at a URL; pass an InputFile to upload, and the request becomes a multipart/form-data upload automatically:

use Telegram\Builders\InputFile;

$telegram->sendPhoto($chatId, 'AgACAgQAAxkBAA...');           // an existing file_id
$telegram->sendPhoto($chatId, 'https://example.com/cat.jpg'); // a URL Telegram fetches
$telegram->sendPhoto($chatId, InputFile::fromPath('cat.jpg'));// an upload

See Keyboards and files for the details, including files nested inside media groups.

Methods this build has not heard of

The generated methods describe one Bot API version. If you are pointed at a server that is ahead of it, or a local Bot API server with an extension of its own, call it by name:

$telegram->request('someFutureMethod', ['chat_id' => $chatId], ['Message']);

The third argument is the Telegram type the result should be hydrated as; leave it out to get the raw decoded value. Everything else - encoding, uploads, rate limiting, error mapping - works the same.

The endpoint list

Telegram\Http\Endpoint holds every method name as a constant, which is useful when a method name is passed around rather than called directly:

use Telegram\Http\Endpoint;

Endpoint::SEND_MESSAGE;   // 'sendMessage'
Endpoint::all();          // every method this build knows about

Search results