Looking to hire Laravel developers? Try LaraJobs

laravel-telegram maintained by ozkanozcan

Description
Laravel 10-13 Telegram Bot notification channel package
Author
Last update
2026/08/09 20:46 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

Laravel Telegram Notifier

Tests Latest Version on Packagist PHP Version Laravel Version License: MIT

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

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

  1. Open Telegram and search for @BotFather.
  2. Start a conversation and send the command:
    /newbot
    
  3. 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).
  4. BotFather will respond with your Bot Token:
    Done! Congratulations on your new bot.
    Use this token to access the HTTP API:
    1234567890:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    
  5. Copy the token and add it to your .env file:
    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

  1. Search for @userinfobot on Telegram.
  2. Start a conversation and send /start.
  3. The bot will reply with your user information including your Id field — that is your chat_id.

Alternatively:

  1. Send any message to your own bot (@yourbotname).
  2. Open this URL in your browser (replace YOUR_TOKEN):
    https://api.telegram.org/botYOUR_TOKEN/getUpdates
    
  3. Find the "chat" object in the JSON response:
    "chat": {
        "id": 123456789,
        "first_name": "John",
        "type": "private"
    }
    
  4. The "id" value is your chat_id.

Group Chat ID

  1. Add your bot to the group.
  2. Send a message in the group (mention the bot or just type anything).
  3. Open https://api.telegram.org/botYOUR_TOKEN/getUpdates.
  4. Look for "chat": {"id": -100xxxxxxxxxx} — group IDs start with -100.

Channel ID

For public channels use the channel username: @yourchannel
For private channels:

  1. Forward any message from your channel to @userinfobot.
  2. 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

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes following Conventional Commits
  4. 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.