Configure Mailtrap And Multiple Email Services in Laravel Applications

Laravel is an easy-to-understand PHP-based framework. It makes writing complex features extremely easy; sometimes, just one function does it all. While the Laravel application is under development, one might also need to test email functionality.

Emails play an important role in any application. With emails, we can notify users of new app features, available offers, and security events. It is essential to test your emails before sending them to real customers. Mailtrap can be helpful for testing emails in the development or production phase.

What is Mailtrap?

Mailtrap is a service for testing emails in the development environment or sending test emails before sending them to real customers. It simulates the real SMTP server and delivers your emails from the localhost or staging website to a test email on mailtrap.

Once Mailtrap is set up, developers can build functionality to allow the marketing team to send emails to a mailtrap inbox to see how emails are rendered.

How to set up Mailtrap in Laravel application?

Laravel supports many email services out of the box, including SMTP, Mailgun, Postmark, Amazon SES, and Sendmail. Laravel provides mail configuration file located at config/mail.php. In mail.php we can set up a default email service and its credentials.

But before editing the mail configuration file, let’s get the mailtrap credentials by creating a mailtrap account. Visit mailtrap website and sign up for an account. Go for a free plan to test their services. The free plan allows us to send 500 emails per month and provides one inbox. It’s enough for small applications.

Once you have signed up, open the Demo inbox, and there will be SMTP credentials for your account.

In the SMTP Settings tab, select Laravel from the dropdown menu. It will show you the configuration to use in the Laravel application.

Mailtrap configuration credentials
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=mailtrap_username
MAIL_PASSWORD=mailtrap_password
MAIL_ENCRYPTION=tls

The easiest way to set up mailtrap is to copy the above configuration to the application’s .env file. That’s it. Now, whenever you send emails, your application will deliver emails to the mailtrap inbox. This is basic and useful if you are not planning to use mailtrap in production.

After deploying the Laravel app in production, you can replace mailtrap with mailgrid, ses, mailgun, etc.

As I said above, if you send emails to your customers, it is better to test how the emails are rendered. Laravel lets you easily switch between mailing services, whether the application is in a development or production environment.

Use multiple email services in Laravel app

First of all, we can set a default email service in config/mail.php. Let’s say my application is in production, and I have set up mailgun as my default mailing service. Now, I need to switch to mailtrap to send test emails without changing the configuration file manually.

Use Swift_Mailer to switch mail services

We can accomplish this by creating an instance of Swift_Mailer. It will allow us to switch to a different service while a PHP script is executing. Here is how it works –

Let’s say the user clicks ‘Send test email’. This will run the following code to backup the current configuration set a new mailtrap configuration, send emails, and switch back to the default configuration after the email is sent.

First of all, import all necessary classes –

use Mail;
use Swift_SmtpTransport;
use Swift_Mailer;

Backup current configuration –

$backup = Mail::getSwiftMailer();

Set mailtrap configuration –

$transport = new Swift_SmtpTransport('smtp.mailtrap.io', 2525, 'tls');
$transport->setUsername('mailtrap_username');
$transport->setPassword('mailtrap_password');

$mailtrap = new Swift_Mailer($transport);

Note

In the above setUsername and setPassword function, replace mailtrap_username and mailtrap_password with your mailtrap username and password.

Set mailtrap mailer –

Mail::setSwiftMailer($mailtrap);

Send an email with mailtrap –

Mail::send();

Reset back to the main configuration –

Mail::setSwiftMailer($backup);

With this method, you can allow the marketing team to test their emails before sending them to real customers. We can pass a request parameter to detect if the team member wants to send live or test emails and change the mailer accordingly.

Basic example of using multiple mail services

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Mail;
use Swift_SmtpTransport;
use Swift_Mailer;
class UsersController extends Controller
{
    public function test(Request $request) {
        if ($request->has('testing')) {
            // backup mailing configuration
            $backup = Mail::getSwiftMailer();
            // set mailing configuration
            $transport = new Swift_SmtpTransport('smtp.mailtrap.io', 2525, 'tls');
            $transport->setUsername('mailtrap_username');
            $transport->setPassword('mailtrap_password');
            $mailtrap = new Swift_Mailer($transport);
            // set mailtrap mailer
            Mail::setSwiftMailer($mailtrap);
            $beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
            $beautymail->send('emails.test', [], function($message)
            {
                $message
                    ->from('from@domain.com')
                    ->to('to@email.com', 'Chill Pill')
                    ->subject('Email subject');
            });
            // reset to default configuration
            Mail::setSwiftMailer($backup);
            return "Email was sent!";
        }
        // send email using beautymail
        $beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
        $beautymail->send('emails.live', [], function($message)
        {
            $message
                ->from('from@email.com')
                ->to('to@email.com', 'Chill Pill')
                ->subject('Email subject');
        });
        return "Live email was sent.";
    }
}