stueynet's avatar

Lesson for Sending Bulk Email Reminders

Would be super helpful to see a tutorial on sending bulk reminder emails using Scheduling, Jobs and Queues. This is a complicated problem but something that I think most web apps with users needs to do. The very simplest example is probably the activate your account email reminder. The system needs to look in the DB and find users who have non-active accounts, that were created X days ago. Handling the email sending is sort of unclear. Is each email a Job that gets pushed on the Queue or is the Job some kind of looping bulk email send. Also how do you track what reminders have been sent to whom so that you are not sending the same email to a user every minute once the condition for sending the reminder is triggered (IE a week having passed since they signed up).

The Jobs tutorial here is a great start: https://laracasts.com/series/intermediate-laravel/episodes/11

The Laravel docs use reminder emails an an example here: https://laravel.com/docs/master/queues#writing-job-classes

Again I think this is an advanced tutorial but one that would help a lot of people with real world applications.

0 likes
5 replies
bashy's avatar

You can do this with scheduling. I use beanstalk and it works great (I'm also doing it for reminder emails).

Make a new command (php artisan make:command SendReminderEmails)

Edit the new file app/Console/Commands/SendReminderEmails.php

public function fire()
{
    // Get the users where they haven't activated or w/e
    $pending_users = User::has('emails', '=', 1)
        ->pending()
        ->where('created_at', '<=', Carbon::now()->subDays(3))
        ->get();
    // dd($pending_users);

    foreach ($pending_users as $user) {
        $data = [
            'name' => $user->name,
            'email' => $user->email,
            'subject' => 'Subject Here - Reminder',
            'user_id' => $user->id,
            'token' => $activate_token, // if you need a token or link, just add it and use in the email view
        ];

        Queue::push(new SendReminderEmails($data));
    }
}

Make a new Job (php artisan make:job SendReminderEmail)

protected $data;

public function __construct($data)
{
    $this->data = $data;
}

public function handle()
{
    $data = $this->data;

    Mail::send('emails.reminder_html', $data, function($message) use ($data)
    {
        $message->to($data['email'], $data['name']);
        $message->subject($data['subject']);
    });
}

You will need to add these to app/Console/Kernel.php

protected $commands = [
    'App\Console\Commands\SendReminderEmails',
];

protected function schedule(Schedule $schedule)
{
    $schedule->command('company:reminder-emails')->everyMinute();
}

End notes

Probably got some class names not linked up right (plural/singular) but you get the idea :) If you need to do Bcc, do that instead. I do a check for how many emails users get, that's easy enough to change. Depends on how you want to do it.

5 likes
stueynet's avatar

I know this is old but wanted to follow up. @bashy how do you handle the issue of the system continuously sending the user the same reminder? For example, we don't want to send them an email every minute. Just one. Do you have some thoughts on an elegant way to track whats been sent so the next time the command runs it doesn't send to the same person again?

bashy's avatar

@stueynet See this bit of code? This was a lead system so they only had certain emails to send. I made a pivot table to put the stages of the emails in.

has('emails', '=', 1)
hilmansakti's avatar

hey all, I new in programming and I really need help to make email reminders. I have followed the example above, but I got nothing.... I'm using laravel 5.6 now. can anyone help me? the app/Console/Commands/SendReminderEmails.php file, why it has fire function? and where it called?

Please or to participate in this conversation.