borsaco/telegram-bot-api-bundle
composer require borsaco/telegram-bot-api-bundle
config/packages/telegram.yaml with your bot token(s) and optional proxy settings.use Borsaco\TelegramBotApiBundle\Service\Bot;
public function index(Bot $bot) {
// Use $bot to interact with Telegram API
}
public function sendMessage(Bot $bot, Request $request) {
$chatId = $request->query->get('chat_id');
$message = $request->query->get('message');
$bot->sendMessage([
'chat_id' => $chatId,
'text' => $message,
]);
return new Response('Message sent!');
}
Bot class)./telegram/webhook).Use a controller to process Telegram updates (e.g., messages, callbacks):
public function handleUpdate(Bot $bot, Request $request) {
$update = json_decode($request->getContent(), true);
if (isset($update['message'])) {
$message = $update['message'];
$bot->sendMessage([
'chat_id' => $message['chat']['id'],
'text' => 'Thanks for your message!',
]);
}
}
Send photos, documents, or stickers:
$bot->sendPhoto([
'chat_id' => $chatId,
'photo' => 'https://example.com/image.jpg',
'caption' => 'Check this out!',
]);
Create interactive buttons:
$keyboard = [
'inline_keyboard' => [
[
['text' => 'Option 1', 'callback_data' => 'opt1'],
['text' => 'Option 2', 'callback_data' => 'opt2'],
],
],
];
$bot->sendMessage([
'chat_id' => $chatId,
'text' => 'Choose an option:',
'reply_markup' => json_encode($keyboard),
]);
Process button clicks via webhook:
if (isset($update['callback_query'])) {
$callback = $update['callback_query'];
$bot->answerCallbackQuery([
'callback_query_id' => $callback['id'],
'text' => 'You clicked: ' . $callback['data'],
]);
}
Enable async mode in telegram.yaml for non-blocking calls:
async_requests: true
Use Symfony’s Messenger component to queue Telegram API calls:
use Symfony\Component\Messenger\MessageBusInterface;
public function __construct(MessageBusInterface $bus) {
$this->bus = $bus;
}
public function sendAsync(Bot $bot, $chatId, $message) {
$this->bus->dispatch(new SendTelegramMessage($bot, $chatId, $message));
}
Create commands for reusable bot logic:
// src/Command/SendWelcomeMessage.php
class SendWelcomeMessage implements CommandInterface {
public function __construct(private Bot $bot, private int $chatId) {}
public function handle(): void {
$this->bot->sendMessage([
'chat_id' => $this->chatId,
'text' => 'Welcome to our bot!',
]);
}
}
Dispatch events for bot interactions (e.g., MessageReceivedEvent):
public function handleUpdate(Bot $bot, Request $request) {
$update = json_decode($request->getContent(), true);
if (isset($update['message'])) {
$event = new MessageReceivedEvent($update['message']);
$this->eventDispatcher->dispatch($event);
}
}
ngrok locally for testing:
ngrok http 8000
update payload’s token field matches your bot’s token in production.429 Too Many Requests gracefully:
try {
$bot->sendMessage([...]);
} catch (RateLimitException $e) {
// Retry logic or notify admin
}
async_requests: true, responses may not be immediate. Use callbacks or polling for critical actions.maintenance flag in telegram.yaml only filters developers if developers_id is set. Test thoroughly:
development:
developers_id: [1234567] # Your Telegram user ID
maintenance: true
socks5h), ensure it’s correctly formatted and accessible from your server.Log incoming updates to debug payloads:
public function handleUpdate(Bot $bot, Request $request) {
$this->logger->debug('Raw update:', ['update' => $request->getContent()]);
// Process update...
}
curlSimulate Telegram updates for testing:
curl -X POST http://localhost:8000/telegram/webhook \
-H "Content-Type: application/json" \
-d '{"message": {"text": "test", "chat": {"id": 123}}}'
telegram.yaml and BotFather. A wrong token causes silent failures.Wrap API calls in try-catch blocks:
try {
$response = $bot->getMe();
} catch (TelegramApiException $e) {
$this->logger->error('Telegram API error:', ['error' => $e->getMessage()]);
throw new \RuntimeException('Bot service unavailable');
}
Extend the Bot service for domain-specific logic:
class CustomBot extends Bot {
public function sendWelcomeMessage(int $chatId): void {
$this->sendMessage([
'chat_id' => $chatId,
'text' => 'Welcome! Use /help for commands.',
]);
}
}
Add middleware to preprocess updates (e.g., logging, filtering):
// src/EventListener/TelegramUpdateListener.php
public function onKernelRequest(GetResponseEvent $event) {
if ($event->isMasterRequest() && $event->getRequest()->getPathInfo() === '/telegram/webhook') {
$update = json_decode($event->getRequest()->getContent(), true);
// Custom logic (e.g., block spam)
}
}
Create DTOs for API responses to avoid magic strings:
class TelegramUser {
public function __construct(
public int $id,
public string $firstName,
public ?string $lastName,
public ?string $username
) {}
}
// Usage:
$user = new TelegramUser(
$update['message']['from']['id'],
$update['message']['from']['first_name'],
$update['message']['from']['last_name'] ?? null,
$update['message']['from']['username'] ?? null
);
Store chat states or user data in Doctrine:
// After receiving a message:
$user = $update['message']['from'];
$chat = $this->chatRepository->findOrCreate($user['id'], $user['first_name']);
// Update chat state:
$chat->setLastActiveAt(new \DateTime());
$this->chatRepository->save($chat);
Use TelegramBotApiBundle's Bot interface for mocking in tests:
// tests/Service/BotTest.php
public function testSendMessage() {
$bot = $this->createMock(Bot::class);
$bot->expects($this->once())
->method('sendMessage')
->with(['chat_id' => 12
How can I help you explore Laravel packages today?