This guide explains how to handle incoming webhook updates from Telegram and how to respond to them.
You can create an Update object by several ways:
Additionally, the phptg/transport-psr package provides PsrUpdateFactory
that creates Update object from a PSR-7 ServerRequestInterface.
If Update created by fromJson() method, you can get raw data via getRaw() method:
/**
* @var Phptg\BotApi\Type\Update\Update $update
*/
/**
* @var string $raw Raw data, for example:
*
* {"update_id":33991112,"message":{"message_id":422,"from":{"id":1234567,"is_bot":false,"first_name":"John","last_name":"Doe","username":"john_doe","language_code":"ru","is_premium":true},"chat":{"id":1234567,"first_name":"John","last_name":"Doe","username":"john_doe","type":"private"},"date":1720523588,"text":"Hello!"}}
*/
$raw = $update->getRaw();
/**
* @var array $raw Decoded raw data, for example:
*
* [
* 'update' => 33991112,
* 'message' => [
* 'message_id' => 422,
* 'from' => [
* 'id' => 1234567,
* 'is_bot' => false,
* 'first_name' => 'John',
* 'last_name' => 'Doe',
* 'username' => 'john_doe',
* 'language_code' => 'ru',
* 'is_premium' => true,
* ],
* 'chat' => [
* 'id' => 1234567,
* 'first_name' => 'John',
* 'last_name' => 'Doe',
* 'username' => 'john_doe',
* 'type' => 'private',
* ],
* 'date' => 1720523588,
* 'text' => 'Hello!'
* ],
* ]
*/
$raw = $update->getRaw(decoded: true);Creating Update object from JSON string received from POST request body:
use Phptg\BotApi\Type\Update\Update;
use Phptg\BotApi\ParseResult\TelegramParseResultException;
/**
* @var string $jsonString
*/
try {
$update = Update::fromJson($jsonString);
} catch (TelegramParseResultException $e) {
// ...
}If needed, you can create Update object manually via constructor:
use Phptg\BotApi\Type\Message;
use Phptg\BotApi\Type\Update\Update;
/**
* @var Message $message
*/
$update = new Update(
updateId: 33436234444,
message: $message,
);According to the Telegram Bot API documentation, you can respond to webhook updates by returning a JSON-serialized method in the HTTP response body. This allows you to make one Bot API request without waiting for a response from your server.
The WebhookResponse class represents a method as a response to a webhook. You can create it from any method object:
use Phptg\BotApi\Method\SendMessage;
use Phptg\BotApi\WebhookResponse\WebhookResponse;
$method = new SendMessage(chatId: 12345, text: 'Hello!');
$webhookResponse = new WebhookResponse($method);
// Check if the method is supported for webhook responses (doesn't use InputFile)
if ($webhookResponse->isSupported()) {
$data = $webhookResponse->getData();
// Returns: ['method' => 'sendMessage', 'chat_id' => 12345, 'text' => 'Hello!']
}The package provides a built-in JsonWebhookResponseFactory that creates JSON strings for webhook responses.
Additionally, the phptg/transport-psr package provides
PsrWebhookResponseFactory that creates a PSR-7 ResponseInterface.
The JsonWebhookResponseFactory creates JSON strings for webhook responses:
use Phptg\BotApi\Method\SendMessage;
use Phptg\BotApi\WebhookResponse\JsonWebhookResponseFactory;
use Phptg\BotApi\WebhookResponse\WebhookResponse;
$factory = new JsonWebhookResponseFactory();
// Create JSON from WebhookResponse object
$webhookResponse = new WebhookResponse(new SendMessage(chatId: 12345, text: 'Hello!'));
$json = $factory->create($webhookResponse);
// Or create JSON directly from method
$method = new SendMessage(chatId: 12345, text: 'Hello!');
$json = $factory->byMethod($method);
// Now you can send this JSON in your HTTP response body
header('Content-Type: application/json; charset=utf-8');
echo $json;Webhook responses have an important limitation: they do not support file uploads (methods using InputFile).
This is because webhook responses are sent as JSON, and file uploads require multipart form data.
If you try to create a webhook response with a method that uses InputFile, the following will happen:
isSupported()will returnfalse;getData()will throwMethodNotSupportedException.
use Phptg\BotApi\Method\SendPhoto;
use Phptg\BotApi\Type\InputFile;
use Phptg\BotApi\WebhookResponse\WebhookResponse;
use Phptg\BotApi\WebhookResponse\MethodNotSupportedException;
$method = new SendPhoto(
chatId: 12345,
photo: InputFile::fromLocalFile('/path/to/photo.jpg'),
);
$webhookResponse = new WebhookResponse($method);
if (!$webhookResponse->isSupported()) {
// Method contains InputFile - cannot be sent via webhook response
// You'll need to make a separate API call for this
}
try {
$data = $webhookResponse->getData();
} catch (MethodNotSupportedException $e) {
// Exception: "InputFile is not supported in Webhook response."
}For methods with file uploads, you must use the regular TelegramBotApi instance to make the request separately.