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

zomboy7/telegram-bot-bundle

zomboy7/telegram-bot-bundle is a PHP/Symfony bundle for building Telegram bots. It integrates the Telegram Bot API with configurable services, update and webhook handling, and a clean structure for adding commands and bot logic.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. The composer name (zomboy7/telegram-bot-bundle) and the repo (x-oscarr/TelegramBotBundle) both point at a Symfony-style bundle: it registers services through a DI extension, ships a DependencyInjection/*Extension.php, and expects AppKernel-era registration. If you are working in a Laravel app, read this section as "what to expect inside the vendor directory," then jump to Gotchas and Tips for the Laravel-side alternatives.

For a Symfony project, the minimal path is:

composer require zomboy7/telegram-bot-bundle
  1. Look here first: composer.json (check the symfony/* version constraints — that single line tells you whether this is a Symfony 2/3 bundle or something modern), then DependencyInjection/Configuration.php. That file is the authoritative schema for every config key; the README is frequently stale on these older bundles.
  2. Register the bundle in app/AppKernel.php (Symfony ≤3) or config/bundles.php (Symfony 4+). If there is no src/ + autoload psr-4 mapping for a modern namespace, assume Symfony 3 at the newest.
  3. Configure the token under the bundle's root key (something like telegram_bot: / telegram: — confirm against Configuration.php, not the README).
  4. First use case: send a single outbound message from a controller or console command by injecting the bundle's bot/client service and calling the send method. Verify the token and outbound path before touching webhooks — outbound is the cheapest thing to debug.
# app/config/config.yml — key name must match Configuration.php
telegram_bot:
    token: "%telegram_token%"

If there is no test suite and no CI badge, treat the first hour as reconnaissance: read services.yml, list the public services with bin/console debug:container | grep -i telegram, and only then write code.

Implementation Patterns

Outbound-only first, then inbound. The reliable half of a Telegram integration is sending. Wire a console command that sends a message to your own chat ID and run it. Once that works, you have proven the token, the HTTP client, and the service wiring — everything after that is webhook plumbing.

Pattern: service injection over static calls.

class NotifyCommand extends Command
{
    public function __construct(private TelegramBot $bot) { parent::__construct(); }

    protected function execute(InputInterface $in, OutputInterface $out): int
    {
        $this->bot->sendMessage($in->getArgument('chat_id'), $in->getArgument('text'));
        return Command::SUCCESS;
    }
}

Pattern: webhook controller as a thin adapter. Put the update parsing in the controller and push domain work into a service. Telegram retries on non-2xx and on slow responses, so the controller must return 200 fast and never do heavy work inline.

public function webhookAction(Request $request): Response
{
    $update = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
    $this->messageDispatcher->handle($update); // queue this if it does I/O
    return new Response('', 200);
}

Pattern: route the update by type, not by text. A switch on $update['message'] ?? $update['callback_query'] ?? null in one dispatcher service saves you from a nest of if (isset($update['message']['text'])) checks scattered across controllers.

Pattern: set the webhook from a console command, not by hand. Telegram's setWebhook needs the exact public HTTPS URL plus an optional secret_token; a command makes it reproducible across environments and lets you gate it behind --env=prod.

Integration tip: in a Laravel app, do not try to force this bundle into the framework. Use irazasyed/telegram-bot-sdk or defstudio/telegraph for the same job — both are Laravel-native, actively maintained, and give you a facade plus config publishing. The bundle's only advantage is that it already exists in your vendor/ if a legacy Symfony service depends on it.

Gotchas and Tips

  • Symfony-only, with zero dependents and zero stars. There is no community around this package. Treat it as unmaintained: no security patches, no upstream fixes, no Stack Overflow answers. Pin the exact version in composer.json and vendor the source into your own repo if the project is long-lived.
  • Token handling. These older bundles historically defaulted the token into the container at compile time, which means it can leak via debug:container and into the Symfony profiler. Always source the token from an environment variable or a parameter file excluded from version control, and never commit app/config/parameters.yml with a live token.
  • Webhook vs. long polling. If the bundle wires a getUpdates polling loop, it will conflict with a configured webhook — Telegram returns 409 Conflict on getUpdates while a webhook is set. Call deleteWebhook before switching modes, and remember that getUpdates blocks: a naive loop in a controller will time out your PHP-FPM workers.
  • HTTPS and self-signed certs. A webhook URL must be a publicly reachable HTTPS endpoint with a valid certificate. A staging box behind a self-signed cert will fail silently at setWebhook time unless you explicitly pass an upload/certificate argument.
  • file_get_contents over cURL. If the bundle shells out via file_get_contents() for its HTTP calls, it ignores proxy settings, has no timeout control, and throws warnings instead of exceptions. Wrap every call in try/catch and set default_socket_timeout, or swap the transport for a proper client.
  • Silent config typos. Symfony DI will happily ignore unknown keys unless the extension validates its configuration tree. If a token or timeout value appears to do nothing, run bin/console config:dump-reference <bundle_alias> — if that command errors, the bundle has no reference config and you are flying blind.
  • Extension points are thin. Expect to override the client service via a compiler pass or a service alias rather than a documented hook. Before writing one, check whether the service class is final or has a private constructor — either makes decoration impossible and forces a fork.
  • Debugging tips. Log the raw update body before parsing, log the message_id and chat_id of every outbound send, and always check Telegram's ok field — HTTP 200 with {"ok":false,"description":"..."} is the single most common false-positive in bot integrations.
  • Migrating off it. The bot API surface you actually use is tiny (send message, set webhook, parse update). A clean-room replacement against the raw Bot API is a few hundred lines and removes the dependency entirely — a reasonable move for anything customer-facing.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
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