phpbotgram

BaseRequestHandler
in package
implements RequestHandler

AbstractYes

Abstract base for webhook request handlers.

Port of aiogram.webhook.aiohttp_server.BaseRequestHandler (lines 84–208).

Simplified "webhook reply" approach

The upstream supports returning a TelegramMethod directly as the HTTP response body (the "webhook reply" trick), which saves a round-trip to the Telegram API. Faithfully porting the multipart/form-data serialiser that assembles that response is out of scope for this task.

Current behaviour (v0 simplification): handleRequest always returns 200 OK with } as the body. When the dispatcher's dispatch chain returns a TelegramMethod, it is routed through Dispatcher::silentCallRequest so the API call still happens — just as a second outbound request rather than an inline webhook reply.

The multipart writer and the webhook-reply optimisation are deferred to a later task (Task 6.5 / Phase 6 follow-up).

Background-mode

When $handleInBackground is true, the dispatcher call is detached into an Amp fiber and the 200 response is sent immediately. In-flight fibers are tracked in $backgroundTasks so callers can wait for them on shutdown.

Table of Contents

Interfaces

RequestHandler

Constants

MAX_BODY_BYTES  : mixed = 5 * 1024 * 1024
Maximum number of bytes buffered from the request body.

Properties

$data  : array<string, mixed>
Extra workflow kwargs forwarded to `Dispatcher::feedWebhookUpdate` / `feedRawUpdate` on every request.
$dispatcher  : Dispatcher
$handleInBackground  : bool
$backgroundTasks  : array<int, Future<string|int, void>>
In-flight background-dispatch fibers, keyed by `spl_object_id`.

Methods

__construct()  : mixed
awaitBackgroundTasks()  : void
Await all in-flight background tasks spawned by handleRequestBackground().
close()  : void
Release any resources held by this handler (e.g. bot session pools).
handleRequest()  : Response
Entry-point called by amphp/http-server for every incoming POST.
register()  : void
Register this handler at `$path` using the provided registration callback.
resolveBot()  : Bot
Resolve the `Bot` instance to use for this incoming request.
verifySecret()  : bool
Validate the `X-Telegram-Bot-Api-Secret-Token` header value against the secret registered for `$bot`.
handleRequestBackground()  : Response
Detach the dispatch into a background fiber and return 200 immediately.
handleRequestInline()  : Response
Dispatch synchronously, then detach any `silentCallRequest` into a background fiber so the 200 is returned before the secondary API call completes (avoids one full RTT on Telegram's inbound webhook socket).
trackBackgroundTask()  : void
Register a fire-and-forget fiber in `$backgroundTasks` and wire a self-cleaning `finally` callback so the entry is removed once the fiber settles.

Constants

MAX_BODY_BYTES

Maximum number of bytes buffered from the request body.

public mixed MAX_BODY_BYTES = 5 * 1024 * 1024

5 MiB is far larger than any Telegram update (typically < 64 KiB) and prevents an unbounded-buffer DoS from a malicious client.

Properties

$data read-only

Extra workflow kwargs forwarded to `Dispatcher::feedWebhookUpdate` / `feedRawUpdate` on every request.

protected array<string, mixed> $data

$backgroundTasks

In-flight background-dispatch fibers, keyed by `spl_object_id`.

private array<int, Future<string|int, void>> $backgroundTasks = []

Populated in handleRequestBackground; each entry self-cleans via Future::finally once the fiber settles.

Methods

__construct()

public __construct(Dispatcher $dispatcher[, bool $handleInBackground = false ][, array<string, mixed> $data = [] ]) : mixed
Parameters
$dispatcher : Dispatcher
$handleInBackground : bool = false
$data : array<string, mixed> = []

Extra kwargs forwarded to feedWebhookUpdate.

awaitBackgroundTasks()

Await all in-flight background tasks spawned by handleRequestBackground().

public awaitBackgroundTasks() : void

Call this during graceful shutdown (Setup::register and AmphpServer::run wire it into the onStop callback) to ensure FSM writes and outbound API calls complete before the server shuts down.

close()

Release any resources held by this handler (e.g. bot session pools).

public abstract close() : void

Mirrors upstream BaseRequestHandler.close(). The webhook server adapter should call this method when the HTTP server shuts down.

handleRequest()

Entry-point called by amphp/http-server for every incoming POST.

public final handleRequest(Request $request) : Response

Flow:

  1. Resolve the bot for this request.
  2. Check the secret token header.
  3. Dispatch in-line or in the background depending on $handleInBackground.
Parameters
$request : Request
Return values
Response

register()

Register this handler at `$path` using the provided registration callback.

public register(callable(string, RequestHandler): void $registerRoute, string $path) : void

Since amphp/http-server-router is an optional dependency not bundled in this project, the caller supplies a routing callback rather than a concrete router type. Typical usage with amphp/http-server-router:

$handler->register(
    fn (string $path, RequestHandler $h) => $router->addRoute('POST', $path, $h),
    '/webhook',
);
Parameters
$registerRoute : callable(string, RequestHandler): void

A callback that registers a POST route for the given path.

$path : string

The URL path to bind (e.g. '/webhook').

resolveBot()

Resolve the `Bot` instance to use for this incoming request.

public abstract resolveBot(Request $request) : Bot

For single-bot setups this typically just returns the pre-configured bot; multi-token setups may inspect the URL path or a header.

Parameters
$request : Request

The incoming HTTP request.

Return values
Bot

verifySecret()

Validate the `X-Telegram-Bot-Api-Secret-Token` header value against the secret registered for `$bot`.

public abstract verifySecret(string $telegramSecretToken, Bot $bot) : bool

Return true to accept the request; false to reject with 401. The default implementation on the abstract base has no body — every concrete subclass must override this method.

Parameters
$telegramSecretToken : string

The raw header value (may be empty when the header is absent).

$bot : Bot

The bot resolved for this request.

Return values
bool

handleRequestBackground()

Detach the dispatch into a background fiber and return 200 immediately.

private handleRequestBackground(Bot $bot, Request $request) : Response

The response is sent before the Telegram update has been processed. Any TelegramMethod produced by a handler is routed via silentCallRequest inside the background fiber.

In-flight fibers are tracked in $backgroundTasks so callers can drain them on shutdown (e.g. via Future\await($this->backgroundTasks) in a shutdown observer).

Parameters
$bot : Bot
$request : Request
Return values
Response

handleRequestInline()

Dispatch synchronously, then detach any `silentCallRequest` into a background fiber so the 200 is returned before the secondary API call completes (avoids one full RTT on Telegram's inbound webhook socket).

private handleRequestInline(Bot $bot, Request $request) : Response

Simplified from upstream: the result TelegramMethod (if any) is routed via silentCallRequest rather than embedded in the HTTP response body. See class-level docblock for the deferral rationale.

Parameters
$bot : Bot
$request : Request
Return values
Response

trackBackgroundTask()

Register a fire-and-forget fiber in `$backgroundTasks` and wire a self-cleaning `finally` callback so the entry is removed once the fiber settles.

private trackBackgroundTask(Future<string|int, void> $task) : void

Any exception thrown inside $task is caught and demoted to an E_USER_WARNING so that a single failing fiber cannot prevent awaitBackgroundTasks() from completing and thereby block the close() / emitShutdown() shutdown sequence.

Shared by both handleRequestInline (silentCallRequest fiber) and handleRequestBackground (full-dispatch fiber).

Parameters
$task : Future<string|int, void>
On this page

Search results