ozkanozcan / laravel-telegram
Laravel 10-13 Telegram Bot notification channel package
Requires
- php: ^8.2
- illuminate/http: ^10.0|^11.0|^12.0|^13.0
- illuminate/notifications: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
This package is auto-updated.
Last update: 2026-08-09 19:21:40 UTC
README
A clean, zero-dependency Telegram Bot notification channel for Laravel 10, 11, 12, and 13.
Send messages, photos, and documents directly from your Laravel application via the Telegram Bot API.
Table of Contents
- Requirements
- Installation
- Step 1 — Create a Telegram Bot
- Step 2 — Get Your Chat ID
- Step 3 — Configure the Package
- Basic Usage
- Laravel Notifications
- Facade Usage
- TelegramMessage Reference
- Inline Keyboard Buttons
- Message Formatting
- Artisan Command
- Language Files
- Configuration Reference
- Error Handling
- Testing
- Changelog
- Contributing
- License
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.2 |
| Laravel | 10.x / 11.x / 12.x / 13.x |
Installation
Install the package via Composer:
composer require ozkanozcan/laravel-telegram
Laravel's auto-discovery will register the service provider and Telegram facade automatically.
Publish the configuration file:
php artisan vendor:publish --tag=telegram-config
Publish language files (optional — required only to customise messages):
php artisan vendor:publish --tag=telegram-lang
Step 1 — Create a Telegram Bot
- Open Telegram and search for @BotFather.
- Start a conversation and send the command:
/newbot - Follow the prompts:
- Choose a display name for your bot (e.g.
My Laravel App). - Choose a username — must end with
bot(e.g.mylaravelapp_bot).
- Choose a display name for your bot (e.g.
- BotFather will respond with your Bot Token:
Done! Congratulations on your new bot. Use this token to access the HTTP API: 1234567890:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Copy the token and add it to your
.envfile:TELEGRAM_BOT_TOKEN=1234567890:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keep your token secret. Anyone with this token can control your bot.
Step 2 — Get Your Chat ID
The chat ID is the unique identifier of the conversation your bot should send messages to.
It can be a personal chat, a group, or a channel.
Personal Chat ID
- Search for @userinfobot on Telegram.
- Start a conversation and send
/start. - The bot will reply with your user information including your Id field — that is your
chat_id.
Alternatively:
- Send any message to your own bot (
@yourbotname). - Open this URL in your browser (replace
YOUR_TOKEN):https://api.telegram.org/botYOUR_TOKEN/getUpdates - Find the
"chat"object in the JSON response:"chat": { "id": 123456789, "first_name": "John", "type": "private" }
- The
"id"value is yourchat_id.
Group Chat ID
- Add your bot to the group.
- Send a message in the group (mention the bot or just type anything).
- Open
https://api.telegram.org/botYOUR_TOKEN/getUpdates. - Look for
"chat": {"id": -100xxxxxxxxxx}— group IDs start with-100.
Channel ID
For public channels use the channel username: @yourchannel
For private channels:
- Forward any message from your channel to @userinfobot.
- It will show the channel ID (e.g.
-1001234567890).
Add the chat ID to your .env:
TELEGRAM_CHAT_ID=123456789
Step 3 — Configure the Package
Add these variables to your .env file:
TELEGRAM_BOT_TOKEN=1234567890:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TELEGRAM_CHAT_ID=123456789 TELEGRAM_PARSE_MODE=HTML
Verify your setup with the built-in Artisan command:
php artisan telegram:test
Basic Usage
Send a simple message
use OzkanOzcan\LaravelTelegram\TelegramBot; use OzkanOzcan\LaravelTelegram\TelegramMessage; $bot = app(TelegramBot::class); $bot->sendMessage( config('telegram.chat_id'), TelegramMessage::create('Hello from Laravel! 🚀')->html() );
Send a plain string
$bot->sendMessage(config('telegram.chat_id'), 'Hello World!');
Laravel Notifications
This is the recommended way to use the package in Laravel applications.
1. Add routing to your notifiable model
// app/Models/User.php use OzkanOzcan\LaravelTelegram\TelegramChannel; use OzkanOzcan\LaravelTelegram\TelegramMessage; class User extends Authenticatable { public function routeNotificationForTelegram(): string|int|null { // Return the user's personal Telegram chat_id stored in the database, // or fall back to the application-wide default. return $this->telegram_chat_id ?? config('telegram.chat_id'); } }
2. Create a notification class
php artisan make:notification OrderShipped
// app/Notifications/OrderShipped.php namespace App\Notifications; use Illuminate\Notifications\Notification; use OzkanOzcan\LaravelTelegram\TelegramChannel; use OzkanOzcan\LaravelTelegram\TelegramMessage; class OrderShipped extends Notification { public function __construct(private readonly Order $order) {} public function via(object $notifiable): array { return [TelegramChannel::class]; } public function toTelegram(object $notifiable): TelegramMessage { return TelegramMessage::create() ->html() ->content( "📦 <b>Order Shipped!</b>\n\n" . "Order: <code>#{$this->order->id}</code>\n" . "Customer: {$this->order->customer_name}\n" . "Total: <b>\${$this->order->total}</b>" ) ->button('Track Order', route('orders.track', $this->order)) ->disablePreview(); } }
3. Dispatch the notification
// Send to a specific user $user->notify(new OrderShipped($order)); // Send to multiple users Notification::send(User::all(), new OrderShipped($order));
Facade Usage
The Telegram facade is available after auto-discovery:
use OzkanOzcan\LaravelTelegram\TelegramFacade as Telegram; use OzkanOzcan\LaravelTelegram\TelegramMessage; // Send a message Telegram::sendMessage( config('telegram.chat_id'), TelegramMessage::create('🔔 New user registered!')->html() ); // Send a photo Telegram::sendPhoto( config('telegram.chat_id'), 'https://example.com/photo.jpg', ['caption' => 'Check out this photo!'] ); // Send a document Telegram::sendDocument( config('telegram.chat_id'), 'https://example.com/report.pdf', ['caption' => 'Monthly Report'] ); // Raw API call Telegram::request('sendMessage', [ 'chat_id' => config('telegram.chat_id'), 'text' => 'Hello!', ]); // Check bot info $me = Telegram::getMe(); echo $me['username']; // yourbot
TelegramMessage Reference
use OzkanOzcan\LaravelTelegram\TelegramMessage; $message = TelegramMessage::create('Your text here') // ── Content ───────────────────────────────────── ->text('Override text') // Set message text ->content('Alias for text()') // Alias // ── Parse mode ────────────────────────────────── ->html() // HTML parse mode ->markdown() // Markdown parse mode ->markdownV2() // MarkdownV2 parse mode ->parseMode('HTML') // Custom parse mode string // ── Behaviour ─────────────────────────────────── ->disablePreview() // Disable link preview ->silent() // Send without notification sound // ── Recipient override ─────────────────────────── ->to(123456789) // Override chat_id for this message // ── Inline keyboard ────────────────────────────── ->button('Label', 'https://...') // URL button (new row) ->callbackButton('Label', 'data') // Callback data button (new row) ->buttonRow([ // Multiple buttons in one row ['text' => 'A', 'url' => 'https://a.com'], ['text' => 'B', 'url' => 'https://b.com'], ]);
Inline Keyboard Buttons
TelegramMessage::create('Choose an option:') ->html() ->button('📖 Documentation', 'https://laravel.com/docs') ->button('🐙 GitHub', 'https://github.com') ->buttonRow([ ['text' => '✅ Accept', 'callback_data' => 'accept'], ['text' => '❌ Decline', 'callback_data' => 'decline'], ]);
Message Formatting
HTML (recommended)
TelegramMessage::create( "<b>Bold</b>, <i>Italic</i>, <u>Underline</u>\n" . "<code>Inline code</code>\n" . "<pre>Block code</pre>\n" . '<a href="https://example.com">Link text</a>' )->html();
Supported HTML tags: <b>, <i>, <u>, <s>, <code>, <pre>, <a href>, <tg-spoiler>
Markdown
TelegramMessage::create( "*Bold*, _Italic_\n`Inline code`\n```Block code```" )->markdown();
Artisan Command
Test your bot configuration without writing any code:
# Basic test — uses token from config and sends to default chat_id php artisan telegram:test # Override chat_id php artisan telegram:test --chat_id=123456789 # Send a custom message php artisan telegram:test --message="Hello from artisan!"
Language Files
The package ships with en and tr language files.
Publish them to customise or add new locales:
php artisan vendor:publish --tag=telegram-lang
Files will be placed at lang/vendor/telegram/{locale}/telegram.php.
To use translations in your own code:
trans('telegram::telegram.missing_token'); trans('telegram::telegram.api_error', ['code' => 429, 'description' => 'Too Many Requests']);
To add a new locale (e.g. German), create:
lang/vendor/telegram/de/telegram.php
and add the same keys as the en file.
Configuration Reference
After publishing the config (php artisan vendor:publish --tag=telegram-config), you can fine-tune config/telegram.php:
| Key | Default | Description |
|---|---|---|
token |
'' |
Bot token from BotFather |
chat_id |
'' |
Default recipient chat ID |
parse_mode |
HTML |
HTML, Markdown, or MarkdownV2 |
disable_web_page_preview |
false |
Disable link previews |
disable_notification |
false |
Silent notifications |
api_url |
Telegram API | Override for proxies |
timeout |
30 |
HTTP read timeout (seconds) |
connect_timeout |
10 |
HTTP connect timeout (seconds) |
retry.times |
3 |
Retry count on HTTP 429 |
retry.sleep_ms |
1000 |
Delay between retries (ms) |
proxy |
null |
HTTP proxy URL |
logging |
false |
Log every sent message |
Error Handling
use OzkanOzcan\LaravelTelegram\Exceptions\TelegramApiException; use OzkanOzcan\LaravelTelegram\Exceptions\TelegramChannelException; use OzkanOzcan\LaravelTelegram\TelegramFacade as Telegram; use OzkanOzcan\LaravelTelegram\TelegramMessage; try { Telegram::sendMessage( config('telegram.chat_id'), TelegramMessage::create('Hello!')->html() ); } catch (TelegramChannelException $e) { // Configuration error (missing token, missing chat_id) logger()->error('Telegram config error: ' . $e->getMessage()); } catch (TelegramApiException $e) { if ($e->isRateLimit()) { // HTTP 429 — bot is sending too many messages logger()->warning('Telegram rate limit hit.'); } elseif ($e->isBotBlocked()) { // HTTP 403 — user blocked the bot logger()->warning('Bot was blocked by user.'); } elseif ($e->isBadRequest()) { // HTTP 400 — invalid parameters logger()->error('Bad Telegram API request: ' . $e->getTelegramDescription()); } else { logger()->error("Telegram API [{$e->getTelegramErrorCode()}]: {$e->getTelegramDescription()}"); } }
Testing
composer install vendor/bin/phpunit
In your own application tests, you can mock TelegramBot to avoid real API calls:
use OzkanOzcan\LaravelTelegram\TelegramBot; use OzkanOzcan\LaravelTelegram\TelegramMessage; $this->mock(TelegramBot::class) ->shouldReceive('sendMessage') ->once() ->with(123456789, Mockery::type(TelegramMessage::class)) ->andReturn(['message_id' => 42]); $user->notify(new OrderShipped($order));
Changelog
See CHANGELOG.md for a history of changes.
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes following Conventional Commits
- Push and open a Pull Request against
development
Please make sure all tests pass before submitting a PR.
License
MIT © Özkan Özcan — Özcan Teknoloji
See LICENSE for full details.