1

I need to send hundreds of emails using different credentials from laravel. Each customer of mine has his/hers mail list and needs to provide their own SMTP server. I process that list and send emails on customer's behalf.

This is what I have so far. It is working, but it is very slow and I don't have many emails so far. I see a problem when I get more emails. Any suggestions on how to improve?

PS- I use cron Console Command and use Kernel to schedule the job.

public function sendMailings($allMailings) {

    foreach ($allMailings as $email) {
        Config::set('mail.host', $email['smtpServer']);
        Config::set('mail.port', $email['smtpPort']); 
        Config::set('mail.username', $email['smtpUser']);
        Config::set('mail.password', $email['smtpPassword']); 
        Config::set('mail.encryption', $email['smtpProtocol']);            
        Config::set('mail.frommmail', trim($email['fromEmail'])); 
        Config::set('mail.fromuser', trim($email['fromUser'])); 
        Config::set('mail.subject', trim($email['subject'])); 
        Config::set('mail.toEmail', trim($email['toEmail'])); 
        Config::set('mail.toName', trim($email['toName'])); 
        Config::set('mail.pretend', false); 

        $email_body = $email['emailBody'];

        Mail::send('emails.availability, compact('email_body')
                , function($message) {
            $message->from(config('mail.username'), config('mail.fromUser'));
            $message->replyTo(config('mail.frommmail'), config('mail.fromUser'));
            $message->to(config('mail.toEmail'), config('mail.toName'))->subject(config('mail.subject'));
        }); 
        Log::info('Mail was sent');
    }
}
Andrew
  • 7,619
  • 13
  • 63
  • 117

2 Answers2

0

Sending e-mail messages directly in web app can drastically slow down the responsiveness of your application. You should always queue your messages.

Instead of Mail::send You can use Mail::queue

and then from cron or manually call

php artisan queue:work

That will process the next item on the queue. This command will do nothing if the queue is empty. But if there’s an item on the queue it will fetch the item and attempt to execute it.

Pawel Dubiel
  • 18,665
  • 3
  • 40
  • 58
  • Sorry, I already running it via cron console command via Kernel – Andrew Jul 19 '16 at 17:59
  • @Andrew Here is interesting answer http://stackoverflow.com/a/26323505/706466 ( ordering by domain, and keeping connection alive ) – Pawel Dubiel Jul 19 '16 at 18:04
  • @Andrew I think still queueing messages would let you execute them in an asynchronous way ( faster ) ( maybe with this https://github.com/barryvdh/laravel-async-queue ) – Pawel Dubiel Jul 19 '16 at 18:14
0

You can not change email provider configs on-the-fly, so you must make new instance of mailer in service container. I did it before, i wrote a method in my own class to get new mailer instance:

 /**
 * @return Mailer
 */
protected function getMailer()
{
    // Changing mailer configuration
    config(['mail.driver' => static::getName()]);

    // Register new instance of mailer on-the-fly
    (new MailServiceProvider($this->container))->register();

    // Get mailer instance from service container
    return $this->container->make('mailer');
}
Morilog
  • 2,935
  • 2
  • 15
  • 15