Comandos personalizados en Laravel con Artisan

Clase 10 de 33Curso Avanzado de Laravel

Resumen

Aprende a crear comandos personalizados en Laravel con Artisan para automatizar tareas críticas. Partimos de un caso práctico: un comando que envía una newsletter por correo a usuarios verificados, usando notificaciones, argumentos opcionales y barra de progreso. Verás cómo estructurar la firma, la descripción, el constructor y el método handle, además de configurar SMTP con Mailtrap para pruebas confiables.

¿Cómo crear un comando personalizado en Laravel con Artisan?

Crear un comando es directo. Laravel ofrece la base y tú defines la lógica. Además de los que trae Artisan, puedes añadir los tuyos con argumentos, opciones y preguntas.

  • Ejecuta el generador desde la terminal.
  • Define la firma y la descripción.
  • Implementa la lógica en handle.
  • Prueba rápido con un dd('hola').
php artisan make command php artisan send newsletter
// Firma y descripción a protected $signature = 'send newsletter'; a protected $description = 'Envía un correo electrónico'; // Prueba rápida en handle dd('hola');

¿Qué define la firma y la descripción?

La firma es el nombre con el que invocas el comando: por ejemplo, send newsletter. La descripción funciona como ayuda para el usuario: "Envía un correo electrónico".

¿Dónde colocar la lógica con handle?

En handle va la lógica de negocio. Puedes inyectar dependencias con el constructor si lo necesitas.

¿Cómo enviar una newsletter con notificaciones y verificación de correo?

Para enviar correos de forma expresiva usaremos notificaciones. Crearemos una notification y filtraremos usuarios que hayan verificado su email. Luego activaremos las rutas de verificación y configuraremos SMTP con Mailtrap.

  • Genera la notificación desde la terminal.
  • Implementa la interfaz de verificación en el modelo usuario: MustVerifyEmail.
  • Filtra por email_verified_at no nulo y recorre la colección de Eloquent con each.
  • Envía con notify(new *NewsletterNotification*).
  • Habilita verificación de rutas pasando ['verified' => true].
  • Configura Mailtrap: integra con Laravel, copia valores y pégalos en tu .env.
php artisan make notification newsletter notification
// Consulta base: usuarios con email verificado $builder = User::whereNotNull('email_verified_at'); // Envío de notificación $user->notify(new NewsletterNotification); // Rutas con verificación habilitada ['verified' => true];

Nota: si la barra de progreso marca error de inicialización, reemplaza "create progress bar" por progress start antes de ejecutar de nuevo.

¿Cómo añadir argumentos, filtros y barra de progreso al comando?

Para más control, agrega un argumento opcional tipo array llamado email. Si lo pasas, el comando enviará solo a esos correos. También usaremos un query builder para componer la consulta, un whereIn para filtrar y una barra de progreso para feedback claro.

  • Argumento opcional tipo array en la firma: email?*.
  • Recupera el argumento con $this->arguments('email').
  • Usa una variable builder para la consulta y aplica whereIn si hay correos.
  • Calcula count para iniciar la barra de progreso.
  • Avanza la barra con progressAdvance en cada envío y ciérrala con progressFinish.
  • Mensajes informativos: "Se enviaron X correos" o "No se envió ningún correo".
// Firma con argumento opcional tipo array protected $signature = 'send newsletter {email?*}'; // Recuperar argumento y construir la query $email = $this->arguments('email'); $builder = User::whereNotNull('email_verified_at'); if ($email) { $builder->whereIn('email', $email); } $count = $builder->count(); $this->output->progressStart($count); // Envío + barra de progreso $builder->each(function ($user) { $user->notify(new NewsletterNotification); $this->output->progressAdvance(); }); $this->output->progressFinish(); // Mensajes $this->info("Se enviaron {$count} correos"); // O, si no hay usuarios: $this->info('No se envió ningún correo');

¿Te animas al reto final? Crea un comando que notifique a los usuarios no verificados registrados hace más de una semana. Cuéntame en comentarios cómo lo resolverías y qué filtros agregarías.