MrMage's avatar

Best practice for sending delayed emails

I am looking for a way to send my users an "upgrade offer" three months after they signed up. Before actually sending that email, I need to re-check that the conditions for the upgrade still apply (i.e. they have neither cancelled nor upgraded in the meantime).

Right now I am considering the following options:

  1. Queuing a "send upgrade offer" job with a 3 month delay. When executed, that job will check whether the conditions still apply, then send the email.
  2. Queueing this is a notification instead and implementing a "dontCheck" method see https://medium.com/@hotmeteor/handling-delayed-notifications-in-laravel-b6699ec30649 for an example.
  3. I could also use the Laravel Snooze package (https://atymic.dev/blog/laravel-snooze/ ) to schedule the notification. However, I still don't understand what advantage that has over queuing the notification itself for delivery at a later date.
  4. Queueing the email itself (see https://laravel.com/docs/6.x/mail#queueing-mail ). This might be the least flexible option, and I am not sure how to re-check the sending conditions at time of delivery in this case.

How would you guys go about doing this? Also, how should one handle the case if some of the serialized models (e.g. the User object) have been deleted in the meantime (between scheduling and actually sending the email)?

0 likes
6 replies
fylzero's avatar

@mrmage I would either send this to a database table and just write a scheduled task to check the date and send emails. Similar approach to using queue.

Or... I would look into the possibility of interfacing to MailChimp or something to see if I could just trigger an email campaign. Email campaigns in MailChimp are designed for this purpose. To run down a timeline of email followups.

I might avoid queuing because a lot of queue systems have a limit on how long you can delay events.

Hope that helps.

23 likes
MrMage's avatar

@fylzero thank you for the reply! What would be the advantage of writing emails to a dedicated table rather than using Laravel's queue system?

fylzero's avatar

@mrmage Just the ability to delay them as long as you wanted. I would still have the scheduler (cron job) pull emails from the database and add those to the queue.

23 likes
aemaddin@gmail.com's avatar

my personal opinion that if i want to send the offers, so i will make a daily scheduler that get all users they are subscribed from 3 months and (add any criterias to filter users), if there is any users has the criterias then he got an instant email with offer, otherwise don't do anything,

i think laravel forge using this kind of scheduler to upgrade composer

i hope that help.

marcelok's avatar

Hi @mrmage

4 years after you I'm wondering the same question.

Can you share what you did? I liked the idea of a job in the queue which includes checking the condition to send the email still applies after 3 months.

Cheers.

Snapey's avatar

@marcelok you don't want to have jobs in the queue for far in the future. You never know when you might need to flush the queue.

Have a scheduled task that runs each day and checks if anyone needs this message

Please or to participate in this conversation.