andrew-gos/telegram-bot-bundle
An advanced, strictly typed, and feature-rich Symfony bundle for creating Telegram bots, built on top of the powerful andrew-gos/telegram-bot library. This bundle fully leverages the Symfony ecosystem to provide a seamless and highly configurable development experience.
bin/console commands to manage webhooks, listen for updates (long-polling), and inspect bot status.Install the bundle into your Symfony project using Composer.
composer require andrew-gos/telegram-bot-bundle
The bundle will be automatically enabled by Symfony Flex.
This is where the magic happens. The bundle's configuration is powerful and allows you to define every aspect of your bot's behavior.
When you install the bundle, our Symfony Flex recipe will automatically generate an initial, well-commented configuration file for you at the following location:
config/packages/andrew_gos_telegram_bot.yaml
This file will serve as a great starting point for your own configuration.
If you have chosen not to use Flex recipes, or if the file was not created for any reason, you can create it manually. Simply run the following command from your project's root directory:
touch config/packages/andrew_gos_telegram_bot.yaml
Here is the minimum configuration required to get a single bot running. This bot will use long-polling.
# config/packages/andrew_gos_telegram_bot.yaml
andrew_gos_telegram_bot:
bots:
# A unique name for your bot
my_first_bot:
factory:
# 'getUpdates' is a shortcut for the long-polling factory
method: 'getUpdates'
arguments:
# Best practice: use environment variables for your token!
$token: '%env(string:TELEGRAM_BOT_TOKEN)%'
# Define at least one handler to process messages
handlers:
- handler: App\Telegram\Handler\DefaultMessageHandler
Now, add your token to the .env file:
# .env
TELEGRAM_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
The bundle's configuration is split into three main sections for each bot: factory, plugins, and handlers.
factory section (Required)This defines how the Telegram service instance is created. You can use one of two shortcuts:
'default': The standard factory, best for webhooks.'getUpdates': The factory for long-polling via the listen command.plugins section (Optional)Plugins are services that run on every incoming update before the main handlers. They are perfect for logging, analytics, or initializing session data.
plugins:
- class: App\Telegram\Plugin\RequestLoggerPlugin
arguments:
$logger: '@monolog.logger.telegram'
handlers section (Required for bot logic)This is the core of your bot. It's a list of handler groups, executed based on priority. A handler group has four parts:
checker (Required): A service that decides if this handler should run for the current update.handler (Required): The service that contains the actual business logic.middlewares (Optional): A chain of services that run after the checker and before the handler.priority (Optional, default 0): A number to control the execution order. Higher priority runs first.Execution Flow: For any update, the bundle checks each handler group from highest to lowest priority. The first group whose
checkerreturns true gets itsmiddlewaresandhandlerexecuted, and the process stops.
This example shows a complex setup with two bots, demonstrating most features.
# config/packages/andrew_gos_telegram_bot.yaml
andrew_gos_telegram_bot:
bots:
# A powerful main bot configured for webhooks.
my_main_bot:
factory:
method: 'default'
arguments:
$token: '%env(string:TELEGRAM_MAIN_BOT_TOKEN)%'
plugins:
- class: App\Telegram\Plugin\RequestLoggerPlugin
arguments:
$logger: '@monolog.logger.telegram'
handlers:
# Handles the '/start' command with high priority.
- checker:
class: App\Telegram\Checker\CommandChecker
arguments: { $command: '/start' }
handler: App\Telegram\Handler\StartCommandHandler
middlewares:
- App\Telegram\Middleware\UserAuthenticationMiddleware
priority: 100
# A fallback handler for any other text message.
# If 'checker' is omitted, it defaults to AnyChecker (always runs).
- handler: App\Telegram\Handler\DefaultMessageHandler
priority: -100
# A simple second bot for sending notifications.
my_notification_bot:
factory:
method: 'getUpdates'
arguments:
$token: '%env(string:TELEGRAM_NOTIFY_BOT_TOKEN)%'
The bundle provides a set of commands to manage your bots. You must always specify the bot's name from your configuration file.
Listen for Updates (Long-Polling)
php bin/console andrew-gos:telegram-bot:listen my_main_bot
Set a Webhook
# The URL must be HTTPS
php bin/console andrew-gos:telegram-bot:set-webhook my_main_bot https://my-domain.com/telegram/webhook
Get Webhook Info
php bin/console andrew-gos:telegram-bot:webhook-info my_main_bot
Delete a Webhook
php bin/console andrew-gos:telegram-bot:delete-webhook my_main_bot
Get Bot Info (useful for checking if the token is correct)
php bin/console andrew-gos:telegram-bot:bot-info my_main_bot
Your bot's logic lives in services. Here are skeletons for the main types.
Checker (App\Telegram\Checker\CommandChecker.php)
A checker must implement CheckerInterface.
<?php
namespace App\Telegram\Checker;
use AndrewGos\TelegramBot\Kernel\Checker\CheckerInterface;
use AndrewGos\TelegramBot\Entity\Update;
readonly class CommandChecker implements CheckerInterface
{
public function __construct(
private string $command,
) {}
public function check(Update $update): bool
{
$message = $update->getMessage();
return $message && $message->getText() === $this->command;
}
}
Handler (App\Telegram\Handler\StartCommandHandler.php)
A handler must implement HandlerInterface.
<?php
namespace App\Telegram\Handler;
use AndrewGos\TelegramBot\Kernel\Handler\HandlerInterface;
use AndrewGos\TelegramBot\Entity\Update;
use AndrewGos\TelegramBot\Telegram;
use AndrewGos\TelegramBot\Request\SendMessageRequest;
class StartCommandHandler implements HandlerInterface
{
public function handle(Update $update, Telegram $telegram): void
{
$chatId = $update->getMessage()->getChat()->getId();
$telegram->getApi()->sendMessage(
new SendMessageRequest($chatId, 'Hello! Welcome to the bot.')
);
}
}
Contributions are welcome! If you've found a bug or have an idea for a new feature, please open an issue on GitHub. If you'd like to contribute code, please open a pull request.
This bundle is released under the MIT license. See the bundled LICENSE file for details.
How can I help you explore Laravel packages today?