Webhooks
This package supports both sides of Telegram webhooks:
outgoing Bot API methods such as
setWebhook,deleteWebhook, andgetWebhookInfo;an optional Laravel webhook receiver route for incoming Telegram
Updatepayloads.
Primary Telegram references:
Configuration
Publish the package config and set the webhook values:
config/telegram-bot.php contains:
The route defaults to POST /telegram-bot/webhook and is protected by X-Telegram-Bot-Api-Secret-Token when secret_token is configured. When require_secret is true, the middleware rejects webhook requests if no secret is configured; this defaults to true when APP_ENV=production.
The configured secret token is validated against Telegram's contract before it is accepted: 1-256 characters, using only A-Z, a-z, 0-9, _, and -. Invalid configured secrets fail closed and are not logged.
Register The Webhook With Telegram
Call setWebhook from a deployment command, Tinker, or your own release automation:
The secret token must be 1-256 characters and may contain only A-Z, a-z, 0-9, _, and -.
The same operation is available through an interactive Artisan command:
Non-interactive example:
Use getWebhookInfo() to inspect webhook status:
Or:
Use deleteWebhook() to switch back to getUpdates:
Or:
See Console commands for all command options.
Handle Incoming Updates
Create a handler class:
Then register it in config/telegram-bot.php:
The handler may return:
nullortrue: the package returns{"ok": true};TelegramWebhookReply: the package returns Telegram-compatible JSON such as{"method":"sendMessage","chat_id":"123","text":"Ready."};an array: the package returns it as JSON;
a string: the package returns it as a plain response;
a Symfony/Laravel
Response: the package returns it directly.
Use TelegramWebhookReply::text($text, chatId: $chatId), TelegramWebhookReply::method('sendChatAction', [...]), or TelegramWebhookReply::fromUpdate($update)->answerCallback('Saved.') when the reply can be sent as Telegram's synchronous webhook response. Webhook replies cannot upload InputFile objects; send files and slow work through an injected bot client or queued job instead. When webhook queueing is enabled, handler return values are processed by the queued job after Telegram already received {"ok": true, "queued": true}, so use the bot client for outbound messages in queued handlers.
Telegram only requires a successful 2xx response. Keep webhook handlers fast; dispatch jobs for slow work.
Dispatcher, Commands, And Fallbacks
For larger bots, leave webhook.handler as null and use the built-in dispatcher maps:
Command handlers implement TelegramWebhookCommandHandler:
The dispatcher checks commands before update-type handlers. It understands /start, /start arguments, and /start@YourBot arguments; when bot_username is configured, commands addressed to another bot are ignored and normal update dispatch continues.
Update-type and fallback handlers implement TelegramWebhookHandler, the same contract used by the single-handler mode. The handlers map uses Telegram update field names such as message, callback_query, pre_checkout_query, poll, and chat_member. A * key may be used as a catch-all command or update handler.
Webhook Middleware
Use telegram-bot.webhook.middleware for application-level webhook pipeline steps that should run before the configured handler, dispatcher, command map, or fallback. This is separate from Laravel route middleware: route middleware protects the HTTP endpoint, while webhook middleware receives the parsed TelegramWebhookUpdate.
Register middleware in config:
Middleware runs in the configured order. It can short-circuit downstream handlers by returning its own result instead of calling $next($update, $botName).
Manual Route Registration
The package auto-registers the configured webhook route by default. If you disable auto-registration, use the Laravel route macro from your own route file:
The macro attaches the same VerifyTelegramWebhookSecret middleware as the default package route.
Events
When dispatch_event is true, every valid update dispatches:
Example listener registration:
Use either a configured handler, events, or both. If both are enabled, the event is dispatched before the handler result is converted into the HTTP response.
TelegramWebhookUpdate
TelegramWebhookUpdate keeps the raw payload and detects all Bot API 10.0 update fields:
For common Telegram objects, use typed accessors when you want IDE-friendly webhook code while keeping the raw payload available:
Direct message-like accessors are also available: message(), editedMessage(), channelPost(), editedChannelPost(), businessMessage(), editedBusinessMessage(), and guestMessage(). Callback query updates are available through callbackQuery(), including typed from() and message() accessors. Inline mode is covered by inlineQuery() and chosenInlineResult(). Payment queries keep their backward-compatible array accessors and add typed shippingQueryData() and preCheckoutQueryData(). Common message media, entities, successful payments, order info, and chat member payloads also have typed object accessors such as photoData(), documentData(), entitiesData(), successfulPaymentData(), orderInfoData(), and newChatMemberData(). The remaining official update families are covered by businessConnection(), deletedBusinessMessages(), purchasedPaidMediaData(), poll(), pollAnswer(), messageReaction(), messageReactionCount(), chatBoost(), removedChatBoost(), and managedBot(). Membership updates are available through myChatMember(), chatMember(), and chatJoinRequest().
Unknown future update fields remain available through payload() and get() even before the SDK adds first-class awareness.
Common Handler Patterns
Message command:
Callback button:
Payment pre-checkout:
Chat member update:
Route And Middleware
The default route is registered by the service provider:
Customize it in config:
Package middleware always validates X-Telegram-Bot-Api-Secret-Token when secret_token is configured. It also fails closed when require_secret is true and the secret is missing. Add rate limiting, IP filtering, or observability middleware in the middleware array when the host application needs it.
The receiver rejects malformed updates before dispatching events or handlers. A valid incoming payload must be JSON and include an integer update_id, matching Telegram's Update object contract.
Queue And Idempotency
By default, webhook handlers run synchronously during the HTTP request. For production handlers that do non-trivial work, enable the queue handoff:
When queueing is enabled, the receiver validates the payload and secret token, dispatches AlexItDev91\LaravelTelegramBot\Laravel\Jobs\TelegramWebhookJob, and returns:
The queued job processes the same TelegramWebhookUpdate through the configured event, handler, dispatcher, command, and fallback pipeline. If the host application does not provide Laravel's bus dispatcher, the receiver logs a warning and processes the update synchronously instead of dropping it.
Telegram can retry webhook deliveries, so enable the cache-backed idempotency guard when handlers are not safe to run twice for the same update_id:
The guard uses the host application's cache repository and add() semantics. A repeated update for the same bot and update_id returns:
If a synchronous handler throws, the idempotency key is released so Telegram retries can be processed. In queued mode, the key is kept after the job is dispatched and Laravel queue retries handle processing failures.
Conversation State
The package includes an opt-in cache-backed conversation store for stateful webhook flows such as profile wizards, support triage, and multi-step admin commands.
Resolve TelegramConversationManager in a handler or middleware. For guided forms, build a TelegramConversationWizard on the update-scoped workflow:
TelegramConversationWizard starts the first step automatically, stores validated values in TelegramConversationContext, returns a result object with reply text, supports /cancel and /back, and uses callback-query data for inline keyboard steps. Use TelegramConversationWorkflow directly when you need a custom state machine with guarded transitions or non-linear storage rules.
Conversation keys are namespaced by bot and the effective chat/user when Telegram provides them. If a cache repository is unavailable, the manager returns DTOs for the current call but does not persist state, and the package logs a safe warning when logging is enabled.
Human Handoff
TelegramHumanHandoff is an optional conversation contract for pausing automation while a support operator works with the user in a private chat, group, forum topic, or external ticket system.
Close the handoff from the original user workflow after the operator resolves it:
Store the original workflow key or ticket ID in the host app when operators resolve cases from another chat. Queue operator notifications for busy support inboxes, keep raw customer text and attachments out of summaries unless necessary, restrict operator chat membership, and keep bot tokens, webhook secrets, and payment data out of tickets and logs.
Observability Events
When telegram-bot.webhook.dispatch_event is true, the Laravel integration dispatches:
AlexItDev91\LaravelTelegramBot\Laravel\Events\TelegramWebhookReceivedAlexItDev91\LaravelTelegramBot\Laravel\Events\TelegramWebhookHandledAlexItDev91\LaravelTelegramBot\Laravel\Events\TelegramWebhookFailedAlexItDev91\LaravelTelegramBot\Laravel\Events\TelegramWebhookQueuedAlexItDev91\LaravelTelegramBot\Laravel\Events\TelegramWebhookDuplicateSkipped
Use these events for metrics, tracing, and low-cardinality operational dashboards. Avoid logging full payloads, chat IDs, message text, tokens, and secret headers from event listeners.
Logging
When telegram-bot.logging.enabled is true, the Laravel integration writes warning/error logs for:
rejected webhook secret tokens and missing required secret configuration;
invalid webhook update payloads;
invalid webhook handler configuration;
webhook handler failures before the exception is rethrown;
Telegram Bot API
ok: falseresponses and transport response failures from Laravel-resolved bot clients.
Log context is intentionally limited to operational metadata such as method names, HTTP status codes, Telegram error codes, update IDs, update types, bot names, and exception classes. The package does not log bot tokens, webhook secret header values, request payloads, response bodies, chat IDs, or message text.
Security Checklist
Use HTTPS for public Telegram webhooks.
Set
TELEGRAM_WEBHOOK_SECRET_TOKENand pass the same value tosetWebhook.Keep
TELEGRAM_WEBHOOK_REQUIRE_SECRET=truein production so a missing secret does not silently expose the route.Keep
TELEGRAM_BOT_LOGGING_ENABLED=trueunless the host application has equivalent monitoring.Do not commit real bot tokens, webhook secrets, chat IDs, logs, or payload dumps.
Avoid long-running work in the webhook request; use
TELEGRAM_WEBHOOK_QUEUE_ENABLED=true.Enable
TELEGRAM_WEBHOOK_IDEMPOTENCY_ENABLED=truewhen duplicate webhook processing would be harmful.Use
allowed_updatesinsetWebhookto reduce unnecessary traffic.Use
getWebhookInfoafter deployment to confirm Telegram sees the expected URL and has no delivery errors.