Datadog collects and monitors your PHP app metrics and distributed traces in real-time with application performance monitoring. Decrease downtime and performance issues with Datadog APM by tracing requests across service boundaries and drilling into individual traces end-to-end with flame graphs. Start your 14-day trial for free today.

How to configure and use multiple SES accounts in a Laravel app

Original – by Freek Van der Herten – 4 minute read

When working on Mailcoach, it was unclear to me how I could use multiple SES (or Mailgun or Postmark) accounts inside a Laravel app. In this short blog post, I'd like to explain that to you.

Laravel 7 introduced the ability to configure multiple mailers. Inside the mail.php config file, there's now a mailers key when an entry for each email provider.

// in config/mail.php

'mailers' => [
    'smtp' => [
        'transport' => 'smtp',
        'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
        'port' => env('MAIL_PORT', 587),
        'encryption' => env('MAIL_ENCRYPTION', 'tls'),
        'username' => env('MAIL_USERNAME'),
        'password' => env('MAIL_PASSWORD'),
    ],

    'ses' => [
        'transport' => 'ses',
    ],

    'mailgun' => [
        'transport' => 'mailgun',
    ],

    'postmark' => [
        'transport' => 'postmark',
    ],

    'sendmail' => [
        'transport' => 'sendmail',
        'path' => '/usr/sbin/sendmail -bs',
    ],

    'log' => [
        'transport' => 'log',
        'channel' => env('MAIL_LOG_CHANNEL'),
    ],

    'array' => [
        'transport' => 'array',
    ],
],

For some of these mailers, the Laravel documentation specifies that you should add some extra configuration values in config/services.php. Here's what you should add to that file if you want to use ses.

// in config/services.php

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'a-ses-region',
],

Here's how you could send a mail using one of these configured mailers.

// send a mail using ses
Mail::mailer('ses')
    ->to($request->user())
    ->send(new YourAwesomeMailable());

// send a mail using smtp
Mail::mailer('smtp')
    ->to($request->user())
    ->send(new YourAwesomeMailable());

This works fine when you want to send mail using different email providers. But how would you send mail using different accounts on the same service? Let's say, for instance, you want to use two SES mailers? How would you do that, there's only one entry in the config/services.php file.

source

The answer lies in the source code! Let's take a look at the code where Laravel is reading the mail config to build the SES transport.

protected function createSesTransport(array $config)
{
    if (! isset($config['secret'])) {
        $config = array_merge($this->app['config']->get('services.ses', []), [
            'version' => 'latest', 'service' => 'email',
        ]);
    }

    $config = Arr::except($config, ['transport']);

    return new SesTransport(
        new SesClient($this->addSesCredentials($config)),
        $config['options'] ?? []
    );
}

Here you can see that if there's no secret set on the config, Laravel will look in the services config file if there are configuration values present in the ses key. So, if you specify a secret in the ses mailer in the mail config file, Laravel will use those values.

So here's how you can define and use multiple SES accounts in one Laravel app:

// in config/mail.php

'mailers' => [
    'ses' => [
        'transport' => 'ses',
		'key' => 'your-ses-key',
		'secret' => 'your-ses-secret',
		'region' => 'a-ses-region',
		'version' => 'latest',
		'service' => 'mail',
    ],
    
    'another-ses' => [
        'transport' => 'ses',
		'key' => 'another-ses-key',
		'secret' => 'another-ses-secret',
		'region' => 'another-ses-region',
		'version' => 'latest',
		'service' => 'mail',
    ],
],

Those versions and service keys are required too. In the source code above, you can see that Laravel only automatically adds those when you've put your configuration in services.php.

With all this in place, you can start using the mailers.

// send a mail using ses
Mail::mailer('ses')
    ->to($request->user())
    ->send(new YourAwesomeMailable());

// send a mail using another ses account
Mail::mailer('another-ses')
    ->to($request->user())
    ->send(new YourAwesomeMailable());

Laravel reads the config for the other mailers like Mailgun and Postmark in a similar fashion. So, if you need to use multiple accounts of the same service, define the config in the mail.php config file, and not in services.php.

(Thanks Taylor, for pointing me in the right direction)

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

Webmentions

Ferdinand AMOI liked on 16th March 2020
Percy Astocaza liked on 16th March 2020
Neil Carlo Faisan Sucuangco liked on 16th March 2020
Karol Krakowiak liked on 16th March 2020
Edwin I Arellano liked on 16th March 2020
Ed Grosvenor liked on 16th March 2020
Jens Twesmann liked on 16th March 2020
José Cage liked on 16th March 2020
Miguel Piedrafita 🚀 liked on 16th March 2020
lost.design liked on 16th March 2020
Mike liked on 16th March 2020
Florian Voutzinos ⚡ liked on 16th March 2020
Lee Overy liked on 16th March 2020
Hardik Shah liked on 16th March 2020