Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Telegram Bot Bundle Laravel Package

tourze/telegram-bot-bundle

tourze/telegram-bot-bundle is a Symfony bundle that streamlines Telegram bot integration in PHP applications. It provides framework wiring for bot services and configuration, making it easier to register bots, process updates, and build messaging or command workflows with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/telegram-bot-bundle is distributed as a Symfony bundle (not a native Laravel package). That single fact shapes everything below: you can use it in a Laravel app, but you will be hand-wiring what Symfony Flex would normally do for you.

Minimal steps:

  1. Pin an exact version. The package is pre-1.0 (0.1.2 → 0.2.0), so minor bumps can carry breaking changes. Use composer require tourze/telegram-bot-bundle:0.2.0 rather than ^0.2 until you've read the diff.
  2. Read the diff first. The 0.2.0 release notes contain only a compare link (0.1.2...0.2.0) — no changelog entries, no migration notes. Before upgrading, open that compare view and scan for changed constructor signatures, renamed service IDs, and changed config keys. Treat this as mandatory, not optional.
  3. Inspect the package internals in vendor/tourze/telegram-bot-bundle/:
    • composer.json — what it depends on (likely a sibling tourze/telegram-bot-api or an HTTP client wrapper). Your real API surface often lives in the dependency, not the bundle.
    • src/DependencyInjection/*Extension.php — the authoritative list of config keys and service definitions.
    • src/Resources/config/*.yaml — service IDs you'll need to reference manually under Laravel.
    • README.md — tourze packages frequently have thin or Chinese-language docs; the code is the documentation.
  4. Bridge the container. In Laravel, register the bundle's services in a service provider ($this->app->singleton(...) per service ID) or, more practically, instantiate the underlying client yourself and use the bundle only as a config-source reference.
  5. First use case: send a single message to a known chat ID from a queued job, then verify by calling getMe / getWebhookInfo. Getting one message out end-to-end validates token config, HTTP client wiring, and error handling in one pass.

If you are on a pure Symfony app, steps 4 collapses to enabling the bundle in config/bundles.php and importing its config — the package is on home turf there.

Implementation Patterns

Configuration as the seam. Put the bot token and any per-bot options in config/services.php (Laravel) or a dedicated config file, and resolve them via env(). Never let the token leak into a service that gets serialized into a queued job payload — pass a bot name, resolve the client inside the job.

Wrap the client, don't inject it everywhere. The bundle's client is a vendor type. Put a thin TelegramNotifier interface in front of it so that a breaking change in 0.3.0 touches one file instead of forty, and so you can fake it in tests.

Queue outbound sends. Telegram enforces roughly 30 messages/second per bot and will return 429 with a retry_after field. Wrap sends in a job with retryUntil/backoff, and use RateLimited middleware keyed per chat to avoid hammering a single conversation — Telegram applies stricter per-chat limits than the global one.

Webhook controller as an invokable. Register a single route (POST /telegram/webhook) excluded from CSRF, validate the X-Telegram-Bot-Api-Secret-Token header against config, then dispatch to a handler. Keep the controller returning 200 fast — Telegram retries on non-2xx and on slow responses, which duplicates updates.

Route updates, don't switch on them. Map message, callback_query, edited_message to handler classes via a small registry rather than a growing match block. This mirrors how the bundle's own event/dispatcher wiring (if present in 0.2.0) is structured and keeps new update types additive.

Multi-bot. If you run more than one bot, use named connections in config and resolve per-name. Avoid static/singleton state in the client — that pattern breaks the moment a second token exists.

Gotchas and Tips

  • Symfony/Laravel container mismatch is the #1 pitfall. Bundles expect autowired services, tagged iterators, and an EventDispatcherInterface. Laravel's container is not a drop-in. Symptoms: "Target [SomeInterface] is not instantiable" at resolve time. Fix by explicitly binding the interfaces the bundle's services consume.
  • No changelog in 0.2.0. With a compare-link-only release, you have no signal about what broke. Diff DependencyInjection/ and any public interfaces; those are where 0.x breaks live. Consider depending on the underlying telegram-bot-api package directly and skipping the bundle entirely if you're on Laravel — the bundle's value is DI glue you're rebuilding anyway.
  • Webhook vs. polling are mutually exclusive. If a previous deployment used getUpdates polling, setWebhook will fail with 409 Conflict: can't use getUpdates while webhook is active. Call deleteWebhook before switching, and script this in your deploy rather than doing it by hand.
  • setWebhook must be re-run whenever the URL or certificate changes, and silently keeps the old URL otherwise. Make it an idempotent artisan command that runs on deploy.
  • File uploads are multipart, not JSON. Sending a document/photo bypasses the JSON body path in most client implementations. If the bundle's client only accepts JSON, you'll need the raw multipart call for sendDocument.
  • Config caching. After changing bot config, run php artisan config:clear (or cache:clear). A stale cached config pointing at a test token is a classic half-hour of confusion.
  • Log the raw response body on failure. Telegram returns {"ok":false,"error_code":...,"description":...} — the description is usually precise ("chat not found", "message is too long", "Bad Request: can't parse entities"). Wrap the client call and log both request method and full response on non-2xx.
  • HTML/Markdown parse modes will bite you. Any user-supplied text interpolated into a parse_mode message must be escaped, or the whole send fails with can't parse entities. Escape at the edge, or omit parse_mode for untrusted content.
  • Timeouts on webhook handlers cause duplicate updates. Telegram's timeout is short. Defer heavy work to a queue and acknowledge immediately.
  • Extension points to watch: the bundle's config tree (in the DI extension) and any service tags it defines (e.g. a handler/command tag). Those are the stable-ish seams; public client methods are the least stable part of a 0.x package.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource