-2

When a certain event is fired, my Laravel based app has to send exactly one transactional email to each user in a mailing list.

Here is the loop code:

$users = User::where('notifiable', 1)->get();

foreach($users as $user) {

    $info = [
        'email' => $user->email,
        'name'  => $user->name
    ];

    $data = [
        'message'   => 'Sample text'
    ];

    Mail::send(['emails.html.notification', 'emails.text.notification',], $data, function($message) use ($info) {
        $message
            ->to($info['email'], $info['name'])
            ->subject('example')
            ->from('admin@example.com','Example');
    });

}

Unfortunately, several users are receiving the same mail multiple times. I can't figure out what's happening:

  • When redirecting the emails to log, I see exactly one mail for each user as expected;
  • Every other events trigger emails to be sent to a single user. However, no one has received multiple emails from these events.

The app is using Sendinblue as an external SMTP service. Some hints I got:

  • The hourly mail quota was very low -> the email were received 3 times (and the queue on Sendinblue was immediately filled)
  • The hourly mail quota was raised 10x -> no more queues on Sendinblue, but now users are receiving the same email up to 7 times!
Enea74
  • 301
  • 2
  • 8
  • 2
    Nothing in your code sets `notifiable` to zero (or false, or anything other than `1`) after sending, so every time this code runs they're going to get notified again, won't they? – ceejayoz Sep 23 '19 at 17:23
  • 1
    `several users are receiving the same mail multiple times` <= How did you know this? Are they receiving the 7 emails at the same time? are you testing this functionality with `PHPUnit`? – Salim Djerbouh Sep 23 '19 at 17:33
  • @ceejayoz - 'notifiable' is used only to detect if user should receive notifications or not, so it must not change. Other emails (just one email to a specific user) are correctly sent just one time as expected. This one (the same notification to all users who wants to receive them) is sent multiple times to each user. – Enea74 Sep 23 '19 at 17:42
  • @CaddyDZ - no problem on the dev server, I'm experiencing this in production – Enea74 Sep 23 '19 at 17:42
  • @Enea74 What's the event that causes this email to be sent? – ceejayoz Sep 23 '19 at 17:43
  • Try using `Sendinblue` to test the emails in local too, it might be a queue issue in that service – Salim Djerbouh Sep 23 '19 at 17:45
  • @ceejayoz - the event is triggered whenever the admin updates the status of a certain object in the database. – Enea74 Sep 23 '19 at 18:24
  • @CaddyDZ - Thanks for the suggestion – Enea74 Sep 23 '19 at 18:24
  • @Enea74 Several questions. Is this task queued? What queue driver are you using, how long does it take to email all your users, and how frequently is your queue worker executed? – ceejayoz Sep 23 '19 at 18:59
  • @ceejayoz - the task was not queued. Now I'm testing it using Laravel's queue driver (jobs are stored in the database) sending 1 email every 10 secs – Enea74 Sep 23 '19 at 19:30

1 Answers1

0

Apparently, queuing the email and setting a delayed event has solved the problem.

Now a new job is requested every 10 seconds.

$users = User::where('notifiable', 1)->get();

$counter = 0;

foreach($users as $user) {

    $payload = [
        'email' => $user->email,
        'name'  => $user->name,
        'message'   => 'Sample text'
    ];

    dispatch(new SendNotification($payload))
    ->delay(now()->addSeconds($counter * 10));

    $counter++;

}

Thanks for your support!

Enea74
  • 301
  • 2
  • 8