Laravel

3 Ways To Use Laravel Dynamic SMTP Settings Like SAAS Does.

Share your learning

How can we use laravel dynamic smtp settings? How can we send laravel mails with custom dynamic smtp configurations?

Few months back, we built a solution for someone in which users can add their own smtp configurations and can send mails to their clients with their smtp details Like SAAS softwares does.

Read Also : Stripe connect for multi vendor with Laravel (SAAS Feature)

Git Repo

git clone https://github.com/SATPAL-BHARDWAJ/Laravel-8-dynamic-smtp-settings.git

We are going to learn 3 different ways to achieve dynamic smtp configurations or settings.

Register a custom mailer in the AppServiceProvider

We can register our own custom mailer in the AppServiceProvider like below in the code.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Swift_Mailer;
use Swift_SmtpTransport;
use Illuminate\Support\Arr;
use Illuminate\Mail\Mailer;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */    public function register()
    {
        $this->createSMTPMailer();
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */    public function boot()
    {
        //
    }

    public function createSMTPMailer() {
        $this->app->bind('custom.smtp.mailer', function ($app, $parameters) {
            $smtp_host = Arr::get($parameters, 'smtp_host');
            $smtp_port = Arr::get($parameters, 'smtp_port');
            $smtp_username = Arr::get($parameters, 'smtp_username');
            $smtp_password = Arr::get($parameters, 'smtp_password');
            $smtp_encryption = Arr::get($parameters, 'smtp_encryption');

            $from_email = Arr::get($parameters, 'from_email');
            $from_name = Arr::get($parameters, 'from_name');

            $replyTo_email = Arr::get($parameters, 'replyTo_email');
            $replyTo_name = Arr::get($parameters, 'replyTo_name');

            $transport = new Swift_SmtpTransport($smtp_host, $smtp_port);
            $transport->setUsername($smtp_username);
            $transport->setPassword($smtp_password);
            $transport->setEncryption($smtp_encryption);

            $swift_mailer = new Swift_Mailer($transport);

            $mailer = new Mailer('custom-smtp-mailer', $app->get('view'), $swift_mailer, $app->get('events'));
            $mailer->alwaysFrom($from_email, $from_name);
            $mailer->alwaysReplyTo($replyTo_email, $replyTo_name);

            return $mailer;
        });
    }
}

Then it will be available everywhere in our application and we can use it as given below in the code.

<?php

namespace App\Traits;

use App\Mail\DynamicSMTPMail;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Swift_Mailer;
use Swift_SmtpTransport;

trait SmtpConfigTrait {

    public function testSMTP() {
      
        try {
            $user = (object) [
                'name' => 'receiver_name',
                'email' => 'receiver_email'
            ];

            $configuration = [
                'smtp_host'    => 'smtp.googlemail.com',
                'smtp_port'    => '465',
                'smtp_username'  => 'username',
                'smtp_password'  => 'password',
                'smtp_encryption'  => 'ssl',
                'from_email'    => 'fromemail',
                'from_name'    => 'fromname',
                'replyTo_email'    => 'replyemail',
                'replyTo_name'    => 'replyname',
            ];
           
            $this->approach1($configuration, $user);

            return true;
        } catch (\Throwable $th) {
            throw $th;
            return false;
        }

    }

    public function approach1($configuration, $user) {
        $mailer = app()->makeWith('custom.smtp.mailer', $configuration);
        $mailer->to( $user->email )->send( new DynamicSMTPMail($user->name, ['email' => $configuration['from_email'], 'name' => $configuration['from_name']]) );
    }

}

In this technique we are not changing default mailer to anything, we have just created our own mailer which we can use anytime with app helper function.

Change the default swiftMailer and restore backup

This is similar to above but here we are changing our default swift mailer with dynamic smtp settings. 

Firstly, we are getting a backup of swiftMailer and then assign new smtp credentials to it. Now, we can use this mailer with default Mail facade.

At the end of this process we have to restore our mailer with default mail settings.

<?php

namespace App\Traits;

use App\Mail\DynamicSMTPMail;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Swift_Mailer;
use Swift_SmtpTransport;

trait SmtpConfigTrait {

    public function testSMTP() {
      
        try {
            $user = (object) [
                'name' => 'receiver_name',
                'email' => 'receiver_email'
            ];

            $configuration = [
                'smtp_host'    => 'smtp.googlemail.com',
                'smtp_port'    => '465',
                'smtp_username'  => 'username',
                'smtp_password'  => 'password',
                'smtp_encryption'  => 'ssl',
                'from_email'    => 'fromemail',
                'from_name'    => 'fromname',
                'replyTo_email'    => 'replyemail',
                'replyTo_name'    => 'replyname',
            ];
           
            
            $this->approach2($configuration, $user);

            return true;
        } catch (\Throwable $th) {
            throw $th;
            return false;
        }

    }

    public function approach2($configuration, $user) {
       
        // backup mailing configuration
        $backup = Mail::getSwiftMailer();

        // set mailing configuration
        $transport = (new Swift_SmtpTransport(
                                $configuration['smtp_host'], 
                                $configuration['smtp_port'], 
                                $configuration['smtp_encryption']))

                    ->setUsername($configuration['smtp_username'])
                    ->setPassword($configuration['smtp_password']);

        $maildoll = new Swift_Mailer($transport);

        // set mailtrap mailer
        Mail::setSwiftMailer($maildoll);

        Mail::to(  $user->email )->send( new DynamicSMTPMail( $user->name, ['email' => $configuration['from_email'], 'name' => $configuration['from_name']] ) );

        // reset to default configuration
        Mail::setSwiftMailer($backup);
    }

}

Use config facade to set dynamic smtp settings Laravel

This is the easiest way to use dynamic smtp settings with laravel but again we have to take backup of current smtp config and at the end need to restore this backup. So, the default mail settings should not be interrupted. 

<?php

namespace App\Traits;

use App\Mail\DynamicSMTPMail;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Swift_Mailer;
use Swift_SmtpTransport;

trait SmtpConfigTrait {

    public function testSMTP() {
      
        try {
            $user = (object) [
                'name' => 'receiver_name',
                'email' => 'receiver_email'
            ];

            $configuration = [
                'smtp_host'    => 'smtp.googlemail.com',
                'smtp_port'    => '465',
                'smtp_username'  => 'username',
                'smtp_password'  => 'password',
                'smtp_encryption'  => 'ssl',
                'from_email'    => 'fromemail',
                'from_name'    => 'fromname',
                'replyTo_email'    => 'replyemail',
                'replyTo_name'    => 'replyname',
            ];
           
            $this->approach3($configuration, $user);

            return true;
        } catch (\Throwable $th) {
            throw $th;
            return false;
        }

    }

    public function approach3($configuration, $user) {
        $backup = Config::get('mail.mailers.smtp');

        Config::set('mail.mailers.smtp.host', $configuration['smtp_host']);
        Config::set('mail.mailers.smtp.port', $configuration['smtp_port']);
        Config::set('mail.mailers.smtp.username', $configuration['smtp_username']);
        Config::set('mail.mailers.smtp.password', $configuration['smtp_password']);
        Config::set('mail.mailers.smtp.encryption', $configuration['smtp_encryption']);
        Config::set('mail.mailers.smtp.transport', 'smtp');
        //Config::set('mail.mailers.smtp.auth_mode', true);
        
        Mail::to(  $user->email )->send(new DynamicSMTPMail( $user->name, ['email' => $configuration['from_email'], 'name' => $configuration['from_name']] ));

        Config::set('mail.mailers.smtp', $backup);
    }
}

That’s it, these are the 3 ways to set dynamic smtp settings with Laravel.

Hope you find this article useful.

Satpal

Recent Posts

How to Switch PHP Versions in XAMPP Easily: Managing Multiple PHP Versions on Ubuntu

Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…

1 year ago

How to Use Coding to Improve Your Website’s SEO Ranking?

Let's understand about how to use coding to improve your website's SEO. In today’s computerized…

1 year ago

Most Important Linux Commands for Web Developers

Let's understand the most important linux commands for web developers. Linux, as an open-source and…

1 year ago

Top 75+ Laravel Interview Questions Asked by Top MNCs

Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…

1 year ago

Mailtrap Integration for Email Testing with Laravel 10

Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…

1 year ago

Firebase Cloud Messaging (FCM) with Ionic 6: Push Notifications

Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…

1 year ago