Enviar Notificaciones en Telegram con Laravel, la Forma Fácil
En este post, te mostraré cómo enviar notificaciones a través de Telegram utilizando Laravel de una forma sencilla y fácil de configurar.
Pasos a Seguir
1. Crear tu Bot en Telegram
-
Iniciar una Conversación con BotFather: Ve a Telegram y busca a @BotFather.
-
Crear un Nuevo Bot: Usa el comando
/newbot
y sigue las instrucciones./newbot
-
Asignar un Nombre: Elige un nombre único para tu bot, como
mysuperbot9000_bot
. Debe terminar con_bot
. -
Obtener el Token: Recibirás un token parecido a
1234567890:AAG2eDLduCRjsgHlms1EezWoCqBlpsSJexE
. Guárdalo de forma segura, ya que lo necesitarás más adelante.
2. Configurar Laravel
-
Instalar el Paquete Necesario: Utiliza Composer para instalar "Telegram Notifications Channel for Laravel".
composer require laravel-notification-channels/telegram
-
Configurar el Token: Añade el token recibido en el archivo
config/services.php
.Nota: Solo sigue estos dos primeros pasos del repositorio. Los demás pasos no son necesarios para nuestro enfoque que utiliza un webhook.
3. Agregar telegram_user_id
al Usuario
-
Editar al migración de usuario o Crear Migración: Agrega la columna
telegram_user_id
a la tabla de usuarios. Por ejemplo:// database/migrations/2014_10_12_000000_create_users_table.php public function up(): void { Schema::create('users', function (Blueprint $table) { // Resto de las columnas… $table->string('telegram_user_id')->nullable(); }); }
4. Crear el Controlador para el Webhook
- Manejo de Mensajes de Telegram: El controlador procesará los mensajes recibidos, extrayendo el ID de usuario de Telegram y asociándolo al usuario correspondiente en tu sistema.
<?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)
{
// Extrae el texto del mensaje recibido del webhook de Telegram
$message = Arr::get($request->all(), 'message.text');
// Extrae el ID del usuario de Telegram que envía el mensaje
$telegramUserId = Arr::get($request->all(), 'message.from.id');
// Extrae el código después del comando '/start' y lo limpia de espacios
$code = trim(Arr::get(explode('/start', $message ?? ''), 1, ''));
// Si no hay código o el ID de Telegram es nulo, termina la ejecución
if (strlen($code) === 0 || $telegramUserId === null) {
return ['success' => true];
}
try {
// Intenta desencriptar el código recibido
$decryptedCode = decrypt($code);
// Verifica si el código desencriptado cumple con el formato 'code:{idusuario}'
if (preg_match('/^code:(\d+)$/', $decryptedCode, $matches)) {
// Extrae el ID del usuario del código
$userId = $matches[1];
// Busca el usuario en la base de datos usando el ID extraído
$user = User::find($userId);
// Si encuentra el usuario, asigna el ID de Telegram y guarda el cambio
if ($user !== null) {
$user->telegram_user_id = $telegramUserId;
$user->save();
}
}
} catch (DecryptException $e) {
// En caso de error en la desencriptación, no realiza ninguna acción
// (puede agregar un manejo de errores personalizado aquí si lo desea)
}
// Devuelve una respuesta de éxito
return ['success' => true];
}
}
- Ruta en Laravel: Agrega una ruta para el webhook en
routes/web.php
.
use App\Http\Controllers\TelegramBotWebhookController;
// ...resto de las rutas
Route::post('telegram/webhook', TelegramBotWebhookController::class)->name('telegram.webhook');
- Excluir de CSRF: En
app/Http/Middleware/VerifyCsrfToken.php
, añade la ruta del webhook a las excepciones.
class VerifyCsrfToken extends Middleware
{
protected $except = [
// Agregar esto:
'telegram/webhook',
];
}
5. Configurar el Webhook en Telegram
- Crear Comando en Laravel: Crea un comando que configure el webhook para tu bot de Telegram.
<?php
<?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);
// La clase `Telegram` no tiene un método para configurar el webhook así que solo
// lo usaremos para obtener la api url y el 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')));
}
}
Nota: Asegúrate de que la ruta del webhook sea accesible públicamente. Si estás trabajando localmente, herramientas como expose pueden ser útiles.
-
Corre el comando que recien creaste
php artisan notifications:set-telegram-webhoook
-
Si todo funciona correctamente, deberías poder ver que el
telegram_user_id
se asigna correctamente en tu base de datos.
6. Probar el Webhook
- Generar Código Encriptado: Utiliza
php artisan tinker
para generar un código encriptado que asocie un ID de usuario con tu bot (en un aplicación real probablemente generaras esté código y se lo darás al usuario para que lo copie).
encrypt('code:1') // Reemplaza '1' con el ID de usuario deseado
- Enviar Mensaje al Bot: Usa el código generado para enviar un mensaje a tu bot con el formato
/start {codigo_encriptado}
.
Ejemplo:
start eyJpdiI6Im1iZzNVZkxUTlMxUGVESlNmdkE0bFE9PSIsInZhbHVlIjoiSDBoVytqOWxuZUNvZjJzaEZEY3paRjJGcmxNYkF2a2x5Q0tteW9vejJ1OD0iLCJtYWMiOiI4ZDU3Mzg0OGQ0YmMwOTM3MzMxMTI1Y2E1OGI2ODFlNTJlM2E0NjdmMzFlMjAwMGVlMDVkZmM5ZDZmYTVhZTJkIiwidGFnIjoiIn0=
7. Enviar una Notificación de Prueba
- Crear una Notificación: Usa la siguiente notificación de ejemplo para probar que recibes mensajes.
<?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)
{
// Contenido con formato markdown
$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);
}
}
- Probar la Notificación: En la consola de Laravel, envía una notificación de prueba.
php artisan tinker
User::find(1)->notifyNow(new App\Notifications\TestNotification())
Deberías de recibir una notificación de parte de tu bot en Telegram.