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

freekmurze

Freek Van der Herten

Posted on March 16, 2020

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

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)

💖 💪 🙅 🚩
freekmurze
Freek Van der Herten

Posted on March 16, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related