6

I'm trying to schedule an email to remind users who have to-do tasks due tomorrow. I made a custom command email:reminder. Here is my code in custom command:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Todo;
use Illuminate\Support\Facades\Mail;

class SendReminderEmail extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:reminder';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Remind users of items due to complete next day';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        /*
         * Send mail dynamically
         */

        /*
         * hardcoded email
         */
        Mail::queue('emails.reminder', [], function ($mail) {
            $mail->to('example@email.com')
                ->from('todoreminder@gmail.com', 'To-do Reminder')
                ->subject('Due tomorrow on your To-do list!');
        }
        );


        $this->info('Reminder email sent successfully!');
    }
}

I hardcoded the email for now to test it, but when I ran php artisan email:reminder, I got an exception of

[InvalidArgumentException]     
  Only mailables may be queued.

I then checked Laravel's documentation, but Task Scheduling and Email Queue are 2 separate topic.

  • How can I achieve sending email queue with task scheduling in Laravel 5.6 please?
  • Also how can I pass data, i.e. to-do items in database into my email view please?

Any help is greatly appreciated!

Wei
  • 85
  • 1
  • 1
  • 7
  • do you have setup the supervisor? – FULL STACK DEV May 06 '18 at 09:03
  • Hi Adnan, could you elaborate please? I don't understand how Supervisor can be used here? I was thinking I might need to create a email job instead, but then how can I schedule the email job to be execute regularly? – Wei May 06 '18 at 09:36
  • supervisor will monitor the queue process. Laravel's mailing system is based on queues. Sending a mail to a user is time consuming and you don't want the user to wait for it. So laravel publishes the mail to a queue, the queue will be handled by a worker. Supervisor will make sure that worker will be restarted when it stops. – Leroy May 06 '18 at 09:51

3 Answers3

2

You should create a command which does exactly as you described, but without the scheduling. You can use the crontab for scheduling or some other task scheduler.

Have you followed Laravel's documentation about mailing? https://laravel.com/docs/5.6/mail

Once you get to the Sending Mail section, you should not create a controller but a command instead.

When that command works, add it to the task scheduler (eg. crontab) to run on a daily basis.

Leroy
  • 1,600
  • 13
  • 23
  • Hi Leroy, please could you elaborate what you mean by "without scheduling", do you mean remove the code in `handle()` method in the command? My scheduling is done in Kernel.php. I have created mail according to the documentation, and made a job. Now I have a SendTodoEmail.php in Mail folder and one in Job folder. But if I put the `Mail::to ...` in command, what should I put in the Queue Job's `handle()`? – Wei May 06 '18 at 10:57
  • I got it, I can schedule a job. Thanks for your help. – Wei May 06 '18 at 11:18
  • I ment that your command should not implement any scheduling. If your command can do what needs to be done. Add the scheduling to a scheduler. Laraval has a scheduler as @DigitalDrifter describes. – Leroy May 06 '18 at 13:28
  • Yeah, I found that later in the documentation. Cheers man! :) – Wei May 06 '18 at 13:43
2

Using the console kernel to schedule queued jobs is easy to do. Laravel offers several wrapper methods that make the cron integration trivial. Here's a basic example:

$schedule->job(new SendTodoReminders())->dailyAt('9:00');
Brian Lee
  • 17,904
  • 3
  • 41
  • 52
  • Yes! I found that later in the documentation too. :D Thank you and have a nice day! – Wei May 06 '18 at 13:41
1
 Mail::queue('emails.reminder', [], function ($mail) {
            $mail->to('example@email.com')
                ->from('todoreminder@gmail.com', 'To-do Reminder')
                ->subject('Due tomorrow on your To-do list!');
        }
        );

is deprecated since Laravel 5.3. Only the Mailables can Queued and it should implement the ShouldQueue interface.

For running jobs you have to configure the queue driver and run php artisan queue:work

FULL STACK DEV
  • 15,207
  • 5
  • 46
  • 66
  • Thank you Adnan, I created a mail class and a job. But how can I running the job regularly (scheduled)? Leroy's method sounds promising, but I didn't get what he said by "without scheduling" – Wei May 06 '18 at 10:28