Good day and Merry Xmas,
Today, I am going to teach you how to schedule a task that can run at a specific time, when building an app, sometimes we might want to automate a task like sending out a newsletter daily/weekly/monthly, sending a report to the admin through email at the end of the day etc. All these task cannot be done manually, so we need a way to schedule it to run at a specific time of the day, week, month, or even every minute, so just relax and let's dive into it
Click on my profile to follow me to get more updates.
Step 1: Setup a new Laravel App
1. Install laravel
composer create-project laravel/laravel laraveljobscheduler
cd laraveljobscheduler/
Step 2: Setup Mail
For more explanation of this step, visit my previous article How to send email in Laravel 8 downwards using Gmail
Step 3: Setup our Gmail Mailable
For more explanation of this step, visit my previous article How to send email in Laravel 8 downwards using Gmail
1. Make the mail
php artisan make:mail Gmail
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class Gmail extends Mailable
{
use Queueable, SerializesModels;
public $details;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($details)
{
$this->details = $details;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject('Mail from Laravel Job Scheduler')
->view('emails.gmail')
->from('Kingsconsult001@gmail.com');
}
}
2. Create the view
<!DOCTYPE html>
<html>
<head>
<title>kings</title>
</head>
<body>
<h1>{{ $details['title'] }}</h1>
<p>{{ $details['body'] }}</p>
<p>Thank you for subscribing</p>
</body>
</html>
Step 4: Create a Job to send the mail
We are going to use a Job to send the mail, so we are going to create a job
php artisan make:job SendEmailJob
A new folder called Jobs will be created at app/, so subsequently new jobs will be stored in this folder,
Let's modify it to send out our mail
<?php
namespace App\Jobs;
use App\Mail\Gmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
class SendEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$details = [
'title' => 'Thank you for subscribing to my newsletter',
'body' => 'You will receive a newsletter every Fourth Friday of the month'
];
Mail::to('kingsconsult001@gmail.com')->send(new Gmail($details));
}
}
When calling a Job, the code inside the handle() method will be the one to run, so that is why we write our code in the handle() method.
From the code above, we import our Mail and Gmail class, we then pass the details of our mail to the Gmail class, my article on Sending mail explains this.
Step 5: Schedule the job to run at the specific time
Lastly, We need to schedule when the job will be run, in order to do this, we are going to add the code in app/Console/Kernel.php, so let's modify the schedule() method
import these classes before the Kernel class
use App\Jobs\SendEmailJob;
use Carbon\Carbon;
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
$now = Carbon::now();
$month = $now->format('F');
$year = $now->format('yy');
$fourthFridayMonthly = new Carbon('fourth friday of ' . $month . ' ' . $year);
$schedule->job(new SendEmailJob)->monthlyOn($fourthFridayMonthly->format('d'), '13:46');
}
From the code above, We want to send out the newsletter every fourth Fridays of the month at 13:46 GMT, I used that day and time so that I will be able to test if my code works,
First, I initialize the present time and extract the month and year, then I assign it to a variable, from the variable I created a time that will run every fourth Friday of the present month and year.
Finally, schedule the job which runs monthly at the day and time that we specified.
**Testing**
Run the scheduler on the terminal
> php artisan schedule:work
![php artisan schedule:work](https://res.cloudinary.com/kingsconsult/image/upload/v1608900618/Schedule%20Job/7_eggcgk.png)
This is the mail I got in my box
![inbox](https://res.cloudinary.com/kingsconsult/image/upload/v1608900625/Schedule%20Job/6_folv46.png)
The complete code can be found in this github repo [Kingsconsult/laravel-schedule-job](https://github.com/Kingsconsult/laravel-schedule-job)
Follow me for more of my articles, you can leave comments, suggestions, and reactions.
I am open to any vacancy as a PHP (Laravel) backend engineer, I am also available for any job.
[click the link to view my profile and follow me] (https://dev.to/kingsconsult)
Thank you for your time
Top comments (3)
This tutorial is a helpful guide for setting up a Laravel cron job to run tasks at specific times. It's great how it covers creating jobs, setting up mail, and efficiently scheduling tasks within Laravel's framework. For a detailed guide you can read this blog on cron jobs in Laravel.
Are you sure this works?
As far as I know, Kernel.exe will be run only once. And at the time it is executed, fourthFridayMonthly is always a day of this month, for example $fourthFridayMonthly->format('d') is 29, but are you sure that 29th day of next month is its fourth Friday?
I think its work if add job in server. server can cronjob run command line every day, every week.