BaseRequestHandler
in package
implements
RequestHandler
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
$dispatcher read-only
protected
Dispatcher
$dispatcher
$handleInBackground read-only
protected
bool
$handleInBackground
= false
$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:
- Resolve the bot for this request.
- Check the secret token header.
- Dispatch in-line or in the background depending on
$handleInBackground.
Parameters
- $request : Request
Return values
Responseregister()
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
BotverifySecret()
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
boolhandleRequestBackground()
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
ResponsehandleRequestInline()
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
ResponsetrackBackgroundTask()
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>