Laravel Send Mail to Inactive Users with Cron Jobs

Hello artisans,

Today I’ll discuss about Cron Jobs, how you can setup Task Scheduling and run through Cron Jobs. Here we will see how we can send mail to the inactive users using Laravel Custom command. We will send this mail using Task Scheduling. So, no more talk and dive into the topic.

Note: Tested on Laravel 8.65.

Table of Contents

  1. Modify User Migration
  2. Create and Configure Notification Class
  3. Create and Configure Custom Command
  4. Modify Your Login Method
  5. Setup Kernel.php File

Modify User Migration

We will start from modify our users table. So, let’s go to the users migration file and paste the following code.

database/migrations/2014_10_12_000000_create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->timestamp('login_at')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Now migrate your commands using below command

php artisan migrate

Create and Configure Notification Class

For creating notification class fire the below command in your terminal

php artisan make:notification NotifyUser

This will create a file under app/Notifications/NotifyUser.php. Now paste the following code into this file.

app/Notifications/NotifyUser.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class NotifyUser extends Notification
{
    use Queueable;

    public function __construct()
    {
        //
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('You are Logged Into our site since One Month')
                    ->action('Get Back There', url('/'))
                    ->line('Thank you for joining shouts.dev community!');
    }

    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

Create and Configure Custom Command

First we need to create a custom command. So, fire the below command in your terminal

php artisan make:command EmailInactiveUsers

This will create a file under app/Console/Commands/EmailInactiveUsers.php. Now paste the following code into this file.

app/Console/Commands/EmailInactiveUsers.php
<?php

namespace App\Console\Commands;

use App\Models\User;
use App\Notifications\NotifyUser;
use Carbon\Carbon;
use Illuminate\Console\Command;

class EmailInactiveUsers extends Command
{

    protected $signature = 'email:users';

    protected $description = 'Email to Inactive Users';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $limit = Carbon::now()->subDay(30);
        $inactive_user = User::where('login_at', '<', $limit)->get();

        foreach ($inactive_user as $user) {
            $user->notify(new NotifyUser());
        }
        return true;
    }
}

Now if you run the the php artisan command in your terminal you can see your command listing there

Modify Your Login Method

For tracking a user login time you need to modify your login method a little bit like below

$user = auth()->user();
$user->login_at = Carbon::now();
$user->save();

Setup Kernel.php File

Finally, we need to setup our kenel.php where we need to register our command. So, paste the following code into the Kernel.php

app/Console/Kernel.php
<?php

namespace App\Console;

use App\Console\Commands\EmailInactiveUsers;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    protected $commands = [
        EmailInactiveUsers::class,
    ];

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('email:users')
            ->weekly();
    }

    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

And that’s it you have reaching at the end of the tutorial. Now if you run the below command in your terminal you can see that your logic is working

php artisan schedule:run

You can also manage this command on scheduling task, you have to add a single entry to your server’s crontab file

* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
OR
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

That’s all for toady. Hope it helps. Thanks for reading.