Install the Package
composer require andrew-gos/telegram-bot
Ensure your project uses PHP 8.2+ and has ext-curl enabled.
Create a Bot Instance
use AndrewGos\TelegramBot\Bot;
use AndrewGos\TelegramBot\Client\TelegramClient;
$client = new TelegramClient('YOUR_BOT_TOKEN');
$bot = new Bot($client);
Handle Updates (Basic Command)
use AndrewGos\TelegramBot\Handler\CommandHandler;
use AndrewGos\TelegramBot\Update\CommandUpdate;
$bot->getHandlerGroup()
->addHandler(new CommandHandler('/start', function (CommandUpdate $update) {
$update->getMessage()->reply('Hello!');
}));
Run the Bot
$bot->run();
For production, use a webhook or long-polling (see BASIC.md).
/start, /help, and custom commands.$bot->getHandlerGroup()
->addHandler(new CommandHandler('/start', fn($update) => $update->reply('Welcome!')))
->addHandler(new CommandHandler('/help', fn($update) => $update->reply('Type /start to begin.')));
README/BASIC.md for update handling.src/Update for update types (e.g., CommandUpdate, MessageUpdate).Register Handlers
Use HandlerGroup to organize handlers by priority or type:
$group = $bot->getHandlerGroup();
$group->addHandler(new CommandHandler('/echo', fn($update) => $update->reply($update->getMessage()->getText())));
$group->addHandler(new TextHandler('ping', fn($update) => $update->reply('pong!')));
Middleware Pipeline Intercept or modify updates before/after handlers:
$bot->getMiddleware()->add(new LoggingMiddleware());
$bot->getMiddleware()->add(new RateLimitMiddleware(10)); // Example custom middleware
Psr\Log\LoggerInterface integration).Symfony\RateLimiter).Framework Integration
AppServiceProvider:
$this->app->singleton(Bot::class, fn($app) => new Bot(
new TelegramClient(config('telegram.bot_token'))
));
Use dependency injection in controllers:
public function handleUpdate(Bot $bot) {
$bot->run(); // Process updates via webhook/long-polling
}
Plugins for Reusability Encapsulate logic (e.g., database integration, analytics) as plugins:
class DatabasePlugin implements PluginInterface {
public function __invoke(Bot $bot): void {
$bot->getMiddleware()->add(new DatabaseLoggingMiddleware());
}
}
$bot->addPlugin(new DatabasePlugin());
Webhook Setup: Configure Telegram’s webhook URL in your Laravel routes:
Route::post('/telegram-webhook', function (Request $request, Bot $bot) {
$bot->processUpdate($request->getContent());
});
Use TelegramClient::setWebhook() for dynamic updates.
Async Processing: Offload heavy tasks (e.g., sending media) to queues:
$bot->getMiddleware()->add(new QueueMiddleware(new LaravelQueue()));
Testing:
Mock TelegramClient and Update objects:
$mockClient = $this->createMock(TelegramClient::class);
$bot = new Bot($mockClient);
$bot->getHandlerGroup()->addHandler(new CommandHandler('/test', fn($update) => $update->reply('test')));
Strict Typing Quirks
Update objects (e.g., CommandUpdate vs. MessageUpdate) causes runtime errors.instanceof checks or generic Update handlers with Update::getType():
$bot->getHandlerGroup()->addHandler(new Handler(
fn($update) => $update instanceof CommandUpdate && $update->getCommand() === '/start',
fn($update) => $update->reply('Start!')
));
Webhook Delays
run() in a try-catch and log errors:
try {
$bot->run();
} catch (Exception $e) {
Log::error('Telegram bot error: ' . $e->getMessage());
}
Middleware Order Matters
LoggingMiddleware after a RateLimitMiddleware won’t log rate-limited requests.$bot->getMiddleware()->add(new RateLimitMiddleware());
$bot->getMiddleware()->add(new LoggingMiddleware());
Long-Polling Timeouts
getUpdates) may time out if the bot is idle.timeout in TelegramClient:
$client = new TelegramClient('TOKEN', 30); // 30-second timeout
Enable Verbose Logging
Inject a Psr\Log\LoggerInterface into TelegramClient:
$client = new TelegramClient('TOKEN', null, null, new MonologLogger());
Inspect Raw Updates Dump raw JSON from Telegram to debug:
$bot->getMiddleware()->add(new HandlerMiddleware(
fn($update) => Log::debug('Raw update:', $update->jsonSerialize())
));
Test Locally with getUpdates
Use long-polling for development:
$client->setWebhook(false); // Disable webhook
$updates = $client->getUpdates(); // Manually fetch updates
Custom Update Types
Extend Update for domain-specific logic:
class CustomUpdate extends Update {
public function getCustomData(): array {
return $this->data['custom_field'] ?? [];
}
}
Dynamic Handlers Register handlers at runtime (e.g., from a database):
$commands = Command::all();
foreach ($commands as $cmd) {
$bot->getHandlerGroup()->addHandler(new CommandHandler(
$cmd->slug,
fn($update) => $update->reply($cmd->response)
));
}
PSR-15 Middleware
Implement Psr\Http\Server\MiddlewareInterface for HTTP-based middleware:
class AuthMiddleware implements MiddlewareInterface {
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
if (!$request->getQueryParams()['auth']) {
return new Response('Unauthorized', 403);
}
return $handler->handle($request);
}
}
Event Dispatching
Use Psr\EventDispatcher\EventDispatcherInterface to trigger events:
$bot->getEventDispatcher()->dispatch(new UpdateReceivedEvent($update));
TelegramClient uses a 60-second timeout for getUpdates. Adjust via constructor:
$client = new TelegramClient('TOKEN', 5); // 5-second timeout
429 Too Many Requests in middleware:
$bot->getMiddleware()->add(new RetryMiddleware());
How can I help you explore Laravel packages today?