Sending Notifications on Telegram with Laravel, the Easy Way
In this post, I will show you how to send notifications via Telegram using Laravel in a simple and easy-to-configure way.
Steps to Follow
1. Create Your Bot in Telegram
-
Start a Conversation with BotFather: Go to Telegram and search for @BotFather.
-
Create a New Bot: Use the
/newbot
command and follow the instructions./newbot
-
Assign a Name: Choose a unique name for your bot, such as
mysuperbot9000_bot
. It must end with_bot
. -
Get the Token: You will receive a token similar to
1234567890:AAG2eDLduCRjsgHlms1EezWoCqBlpsSJexE
. Keep it safe, as you will need it later.
2. Configure Laravel
-
Install the Required Package: Use Composer to install "Telegram Notifications Channel for Laravel".
composer require laravel-notification-channels/telegram
-
Configure the Token: Add the received token in the
config/services.php
file.Note: Only follow these first two steps from the repository. The other steps are not necessary for our approach that uses a webhook.
3. Add telegram_user_id
to the User
-
Edit the User Migration or Create Migration: Add the
telegram_user_id
column to the users table. For example:// database/migrations/2014_10_12_000000_create_users_table.php public function up(): void { Schema::create('users', function (Blueprint $table) { // Rest of the columns… $table->string('telegram_user_id')->nullable(); }); }
4. Create the Controller for the Webhook
- Handling Telegram Messages: The controller will process the messages received, extracting the Telegram user ID and associating it with the corresponding user in your system.
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class TelegramBotWebhookController extends Controller
{
public function __invoke(Request $request)
{
// Extracts the text of the message received from the Telegram webhook
$message = Arr::get($request->all(), 'message.text');
// Extracts the Telegram user ID who sends the message
$telegramUserId = Arr::get($request->all(), 'message.from.id');
// Extracts the code after the '/start' command and cleans it of spaces
$code = trim(Arr::get(explode('/start', $message ?? ''), 1, ''));
// If there's no code or the Telegram ID is null, end execution
if (strlen($code) === 0 || $telegramUserId === null) {
return ['success' => true];
}
try {
// Tries to decrypt the received code
$decryptedCode = decrypt($code);
// Checks if the decrypted code complies with the format 'code:{userid}'
if (preg_match('/^code:(\d+)$/', $decryptedCode, $matches)) {
// Extracts the user ID from the code
$userId = $matches[1];
// Searches for the user in the database using the extracted ID
$user = User::find($userId);
// If the user is found, assigns the Telegram ID and saves the change
if ($user !== null) {
$user->telegram_user_id = $telegramUserId;
$user->save();
}
}
} catch (DecryptException $e) {
// In case of an error in decryption, no action is taken
// (you can add custom error handling here if you wish)
}
// Returns a success response
return ['success' => true];
}
}
- Route in Laravel: Add a route for the webhook in
routes/web.php
.
use App\Http\Controllers\TelegramBotWebhookController;
// ...rest of the routes
Route::post('telegram/webhook', TelegramBotWebhookController::class)->name('telegram.webhook');
- Exclude from CSRF: In
app/Http/Middleware/VerifyCsrfToken.php
, add the webhook route to the exceptions.
class VerifyCsrfToken extends Middleware
{
protected $except = [
// Add this:
'telegram/webhook',
];
}
5. Configure the Webhook in Telegram
- Create Command in Laravel: Create a command that sets up the webhook for
your Telegram bot.
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use NotificationChannels\Telegram\Telegram;
class ConfigureTelegramWebhoook extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'notifications:set-telegram-webhoook';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Set the Telegram webhook for the bot';
/**
* Execute the console command.
*/
public function handle()
{
$telegram = app(Telegram::class);
// The `Telegram` class doesn't have a method to set the webhook so we will just
// use it to get the api url and the token
$apiUri = sprintf('%s/bot%s/%s', $telegram->getApiBaseUri(), $telegram->getToken(), 'setWebhook');
Http::post($apiUri, [
'url' => route('telegram.webhook'),
]);
$this->info(sprintf('Telegram webhook configured to %s !', route('telegram.webhook')));
}
}
Note: Make sure the webhook route is publicly accessible. If you're working locally, tools like expose can be helpful.
-
Run the command you just created
php artisan notifications:set-telegram-webhoook
-
If everything works correctly, you should be able to see that the
telegram_user_id
is correctly assigned in your database.
6. Test the Webhook
- Generate Encrypted Code: Use
php artisan tinker
to generate an encrypted code that associates a user ID with your bot (in a real application you would probably generate this code and give it to the user to copy).
encrypt('code:1') // Replace '1' with the desired user ID
- Send Message to the Bot: Use the generated code to send a message to your bot in the format
/start {encrypted_code}
.
Example:
start eyJpdiI6Im1iZzNVZkxUTlMxUGVESlNmdkE0bFE9PSIsInZhbHVlIjoiSDBoVytqOWxuZUNvZjJzaEZEY3paRjJGcmxNYkF2a2x5Q0tteW9vejJ1OD0iLCJtYWMiOiI4ZDU3Mzg0OGQ0YmMwOTM3MzMxMTI1Y2E1OGI2ODFlNTJlM2E0NjdmMzFlMjAwMGVlMDVkZmM5ZDZmYTVhZTJkIiwidGFnIjoiIn0=
7. Send a Test Notification
- Create a Notification: Use the following example notification to test that you receive messages.
<?php
declare(strict_types=1);
namespace App\Notifications;
use App\Enums\NotificationChannelEnum;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use NotificationChannels\Telegram\TelegramMessage;
class TestNotification extends Notification implements ShouldQueue
{
use Queueable;
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(User $notifiable): array
{
return ['telegram'];
}
public function toTelegram(User $notifiable)
{
// Content with markdown formatting
$content = sprintf("*%s*\n\n%s", 'Test notification!', 'If you see this message, it means that your notification was sent successfully.');
return TelegramMessage::create()
->to($notifiable->telegram_user_id)
->content($content);
}
}
- Test the Notification: In the Laravel console, send a test notification.
php artisan tinker
User::find(1)->notifyNow(new App\Notifications\TestNotification())
You should receive a notification from your bot on Telegram.