Saltar al contenido principal

Introducción

En este tutorial construirás una aplicación Laravel con comandos artisan personalizados usando revolution/laravel-console-starter. Ventajas de usar este starter kit:
  • Configuración rápida: puedes empezar a desarrollar aplicaciones de consola de inmediato, sin configuraciones complejas.
  • Ecosistema Laravel: puedes utilizar la programación de tareas, la base de datos, las notificaciones y todas las funcionalidades de Laravel.
  • Comandos Artisan: crea y gestiona fácilmente comandos personalizados con el potente sistema Artisan de Laravel.
  • Facilidad para testear: puedes escribir tests para tus comandos con el framework de testing de Laravel.

Requisitos previos

Instala el siguiente software.

Configuración del proyecto

1

Crea un nuevo proyecto

Ejecuta en la terminal el siguiente comando.
laravel new my-app --using=revolution/laravel-console-starter --no-interaction
Se crea el directorio my-app con la estructura básica de una aplicación de consola.Durante la instalación se ejecutan automáticamente:
  • Generación del archivo .env a partir de .env.example
  • Configuración de la clave de la aplicación con php artisan key:generate
Estructura principal de directorios:
my-app/
├── app/Console/Commands/   # Ubica aquí tus comandos personalizados
├── .github/workflows/
│   └── cron.yml            # Ejemplo de programación con GitHub Actions
├── config/                 # Configuración de la aplicación
└── routes/console.php      # Registro de comandos
2

Verifica la configuración de entorno

Por defecto el envío de correo está configurado para escribir en el log (MAIL_MAILER=log).Si necesitas enviar correos reales, configura un servicio como Mailgun, Postmark o SES en el archivo .env.

Crear comandos de consola

1

Genera el comando

Crea un nuevo comando con el comando Artisan make:command.
php artisan make:command YourCommandName --command=your:command
  • YourCommandName: nombre de la clase del comando (por ejemplo, SendDailyReport).
  • your:command: nombre de invocación del comando (por ejemplo, report:send-daily).
Se genera app/Console/Commands/YourCommandName.php.
2

Implementa el comando

Edita el archivo generado e implementa la lógica. A continuación tienes un ejemplo de comando Hello World.
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class HelloWorldCommand extends Command
{
    protected $signature = 'hello:world';
    protected $description = 'Displays a hello world message in the log';

    public function handle(): int
    {
        Log::info('Hello, World from Artisan Command!');
        $this->info('Hello, World message has been logged.');
        return Command::SUCCESS;
    }
}
En $signature defines el nombre de invocación y en el método handle() escribes la lógica.
3

Ejecuta el comando

php artisan hello:world
Tras ejecutarlo, se muestra el mensaje en storage/logs/laravel.log y en la consola.

Programación de tareas con GitHub Actions

Con GitHub Actions puedes ejecutar comandos de forma periódica sin necesidad de cron en el servidor.
1

Revisa el archivo de workflow

El starter kit incluye ya configurado el archivo .github/workflows/cron.yml.
name: cron

on:
  schedule:
    - cron: '0 0 * * *'  # Todos los días a las 00:00 UTC

jobs:
  cron:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.5
          coverage: none
      - run: composer install --no-dev -q
      - run: cp .env.example .env
      - run: php artisan key:generate
      - run: php artisan inspire
2

Cambia el comando

Sustituye php artisan inspire por tu propio comando.
- name: Run Command
  run: php artisan your:command
Para ejecutar varios comandos:
- name: Run Commands
  run: |
    php artisan first:command
    php artisan second:command
3

Ajusta la programación

Cambia la expresión cron para configurar la frecuencia de ejecución.
Expresión cronEjecución
0 0 * * *Todos los días a las 00:00 UTC
0 */6 * * *Cada 6 horas
0 0 * * 1Todos los lunes a las 00:00
4

Gestiona la información sensible con secrets

Usa GitHub repository secrets para información sensible como claves de API o contraseñas.Añade los secrets en Settings > Secrets and variables > Actions del repositorio de GitHub y referéncialos en el workflow.
- name: Run Command with Secrets
  run: php artisan your:command
  env:
    API_KEY: ${{ secrets.API_KEY }}
    DB_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}

Funcionalidad de notificaciones

Puedes notificar el resultado o los errores de un comando por correo, Slack, etc.
1

Crea la clase de notificación

php artisan make:notification TaskCompleted
Se genera app/Notifications/TaskCompleted.php.
2

Configura el canal de notificación

Publica los archivos de configuración necesarios.
php artisan config:publish mail
php artisan config:publish services
3

Envía la notificación desde el comando

<?php

namespace App\Console\Commands;

use App\Notifications\TaskCompleted;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Notification;

class ProcessDataCommand extends Command
{
    protected $signature = 'data:process';
    protected $description = 'Procesa los datos y envía notificación al finalizar';

    public function handle()
    {
        $this->info('Procesando datos...');

        // Lógica de procesamiento...

        Notification::route('mail', '[email protected]')
            ->notify(new TaskCompleted('El procesamiento de datos se ha completado correctamente'));

        return Command::SUCCESS;
    }
}
Para más detalles, consulta la documentación de notificaciones de Laravel.

Ejemplos prácticos de aplicación

Ejemplo 1: Monitorización de sitios web con alertas en Slack

Comando que comprueba si un sitio web está online y envía una alerta a Slack si se detecta un problema.
1

Instala el canal de notificación de Slack

composer require laravel/slack-notification-channel
2

Crea el comando y la notificación

php artisan make:command MonitorWebsites --command=monitor:websites
php artisan make:notification WebsiteDown
3

Configura Slack

php artisan config:publish services
Añade la URL del webhook de Slack en .env.
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Actualiza config/services.php.
'slack' => [
    'webhook_url' => env('SLACK_WEBHOOK_URL'),
],
4

Implementa la notificación

Edita app/Notifications/WebsiteDown.php.
<?php

namespace App\Notifications;

use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;

class WebsiteDown extends Notification
{
    public function __construct(
        protected string $website,
        protected string $error,
    ) {}

    public function via($notifiable): array
    {
        return ['slack'];
    }

    public function toSlack($notifiable): SlackMessage
    {
        return (new SlackMessage)
            ->error()
            ->content('¡Alerta: sitio web caído!')
            ->attachment(function ($attachment) {
                $attachment->title($this->website)
                           ->content("Error: {$this->error}")
                           ->timestamp(now());
            });
    }
}
5

Implementa el comando

Edita app/Console/Commands/MonitorWebsites.php.
<?php

namespace App\Console\Commands;

use App\Notifications\WebsiteDown;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;

class MonitorWebsites extends Command
{
    protected $signature = 'monitor:websites {--timeout=10}';
    protected $description = 'Comprueba la disponibilidad de sitios web y envía una alerta a Slack si están caídos';

    protected array $websites = [
        'https://example.com',
        'https://yourwebsite.com',
    ];

    public function handle(): int
    {
        $timeout = (int) $this->option('timeout');
        $webhookUrl = config('services.slack.webhook_url');
        $hasErrors = false;

        foreach ($this->websites as $website) {
            try {
                $response = Http::timeout($timeout)->get($website);
                if ($response->successful()) {
                    $this->info("{$website}: online ✓");
                } else {
                    $error = "HTTP status: " . $response->status();
                    $this->error("{$website}: caído ({$error})");
                    Notification::route('slack', $webhookUrl)
                        ->notify(new WebsiteDown($website, $error));
                    $hasErrors = true;
                }
            } catch (\Exception $e) {
                $this->error("{$website}: error ({$e->getMessage()})");
                Log::error("Fallo al comprobar {$website}", ['error' => $e->getMessage()]);
                Notification::route('slack', $webhookUrl)
                    ->notify(new WebsiteDown($website, $e->getMessage()));
                $hasErrors = true;
            }
        }

        return $hasErrors ? Command::FAILURE : Command::SUCCESS;
    }
}
6

Programa con GitHub Actions

Actualiza .github/workflows/cron.yml.
name: Website Monitoring

on:
  schedule:
    - cron: '*/15 * * * *'  # Cada 15 minutos

jobs:
  monitor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.5
      - run: composer install --no-dev -q
      - run: cp .env.example .env
      - run: php artisan key:generate
      - name: Monitor Websites
        run: php artisan monitor:websites
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

Ejemplo 2: Actualización de cartera de criptomonedas con notificación en Discord

Comando que obtiene los precios de criptomonedas desde la API de CoinGecko y envía la actualización mediante un webhook de Discord.
1

Instala el canal de notificación de Discord

composer require revolution/laravel-notification-discord-webhook
2

Crea el comando y la notificación

php artisan make:command UpdateCryptoPortfolio --command=crypto:portfolio
php artisan make:notification CryptoPortfolioUpdate
3

Configura Discord

Añade la URL del webhook de Discord en .env.
DISCORD_WEBHOOK=https://discord.com/api/webhooks/YOUR/WEBHOOK
Actualiza config/services.php.
'discord' => [
    'webhook' => env('DISCORD_WEBHOOK'),
],
4

Implementa el comando y ejecútalo

Consulta la implementación detallada en el tutorial del repositorio de GitHub.
php artisan crypto:portfolio

Ejemplo 3: Scraping de contenido web y notificación por correo

Comando que hace scraping de contenido de un sitio web y envía el resultado por correo.
1

Crea el comando y la notificación

php artisan make:command WebScraper --command=scrape:website
php artisan make:notification ScrapingCompleted
2

Configura el correo

php artisan config:publish mail
Añade la configuración de correo en el archivo .env.
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
[email protected]
MAIL_FROM_NAME="${APP_NAME}"
3

Implementa el comando y ejecútalo

protected $signature = 'scrape:website {--url=https://example.com} {[email protected]}';

public function handle(): int
{
    $url = $this->option('url');
    $email = $this->option('email');

    $response = Http::timeout(30)->get($url);

    // Procesa el contenido y envía la notificación...
    Notification::route('mail', $email)
        ->notify(new ScrapingCompleted(true, $url, $title, $content));

    return Command::SUCCESS;
}
php artisan scrape:website [email protected]

Próximos pasos

Ya has aprendido los fundamentos para desarrollar aplicaciones de consola con Laravel usando revolution/laravel-console-starter. Para profundizar más:
  • Explora la documentación de Laravel: revisa las funcionalidades que pueden potenciar tu app de consola en la documentación oficial de Laravel.
  • Implementa pruebas: crea tests para tus comandos con el framework de testing de Laravel para asegurar su fiabilidad.
  • Considera crear paquetes: si vas a reutilizar los mismos comandos en varios proyectos, considera publicarlos como paquetes reutilizables de Laravel.
  • Mantente al día: sigue Laravel News y el blog oficial para conocer las buenas prácticas más recientes.
Última modificación el 13 de julio de 2026