Framework: Mailgun Transport for Europe Zone

Created on 29 Jul 2018  路  3Comments  路  Source: laravel/framework

Description:

Recently Mailgun added a new feature which let users choose a new zone for better latency, the European zone.

This zone uses a new URL which differs from this one:
https://github.com/laravel/framework/blob/919eff201844db5c106145248cc02ac1ad671f31/src/Illuminate/Mail/Transport/MailgunTransport.php#L164

The new URL is: https://api.eu.mailgun.net/v3/{domain}/messages.mime

Most helpful comment

If someone is facing the same problem I solved it by extending the default Mailgun transport behaviour.

<?php

namespace App\Mail\Transports;

use GuzzleHttp\ClientInterface;
use Illuminate\Mail\Transport\MailgunTransport;

class ExtendedMailgunTransport extends MailgunTransport
{
    private $zone;

    public function __construct(ClientInterface $client, string $key, string $domain, string $zone)
    {
        $this->setZone($zone);
        parent::__construct($client, $key, $domain);
    }

    private function setZone(string $zone)
    {
        $this->zone = $zone;
    }

    /**
     * Set the domain being used by the transport.
     *
     * @param  string $domain
     * @return string
     */
    public function setDomain($domain)
    {
        $this->url = 'https://api.mailgun.net/v3/' . $domain . '/messages.mime';
        if ($this->zone === 'EU') {
            $this->url = 'https://api.eu.mailgun.net/v3/' . $domain . '/messages.mime';
        }

        return $this->domain = $domain;
    }
}
<?php

namespace App\Mail\Transports;

use Illuminate\Mail\TransportManager;

class CustomTransportManager extends TransportManager
{
    public function createMailgunDriver() {
        $config = $this->app['config']->get('services.mailgun', []);

        return new ExtendedMailgunTransport(
            $this->guzzle($config),
            $config['secret'], $config['domain'], $config['zone']
        );
    }
}
<?php

namespace App\Mail\Transports;

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider
{
    public function registerSwiftTransport()
    {
        if ($this->app['config']['mail.driver'] == 'mailgun') {
            $this->app->singleton('swift.transport', function ($app) {
                return new CustomTransportManager($app);
            });
        } else {
            parent::registerSwiftTransport();
        }
    }
}

And in config/app.php override the default MailServiceProvider with the new one

//Illuminate\Mail\MailServiceProvider::class,
\App\Mail\Transports\MailServiceProvider::class,

Add 'zone' to config/service.php

    'mailgun' => [
        'domain' => env('MAILGUN_DOMAIN'),
        'secret' => env('MAILGUN_SECRET'),
        'zone' => env('MAILGUN_ZONE', 'USA'),
    ],

And finally in your .env file add
MAILGUN_ZONE=EU

Might not be the best way to solve the issue, but it's working for me.

All 3 comments

If someone is facing the same problem I solved it by extending the default Mailgun transport behaviour.

<?php

namespace App\Mail\Transports;

use GuzzleHttp\ClientInterface;
use Illuminate\Mail\Transport\MailgunTransport;

class ExtendedMailgunTransport extends MailgunTransport
{
    private $zone;

    public function __construct(ClientInterface $client, string $key, string $domain, string $zone)
    {
        $this->setZone($zone);
        parent::__construct($client, $key, $domain);
    }

    private function setZone(string $zone)
    {
        $this->zone = $zone;
    }

    /**
     * Set the domain being used by the transport.
     *
     * @param  string $domain
     * @return string
     */
    public function setDomain($domain)
    {
        $this->url = 'https://api.mailgun.net/v3/' . $domain . '/messages.mime';
        if ($this->zone === 'EU') {
            $this->url = 'https://api.eu.mailgun.net/v3/' . $domain . '/messages.mime';
        }

        return $this->domain = $domain;
    }
}
<?php

namespace App\Mail\Transports;

use Illuminate\Mail\TransportManager;

class CustomTransportManager extends TransportManager
{
    public function createMailgunDriver() {
        $config = $this->app['config']->get('services.mailgun', []);

        return new ExtendedMailgunTransport(
            $this->guzzle($config),
            $config['secret'], $config['domain'], $config['zone']
        );
    }
}
<?php

namespace App\Mail\Transports;

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider
{
    public function registerSwiftTransport()
    {
        if ($this->app['config']['mail.driver'] == 'mailgun') {
            $this->app->singleton('swift.transport', function ($app) {
                return new CustomTransportManager($app);
            });
        } else {
            parent::registerSwiftTransport();
        }
    }
}

And in config/app.php override the default MailServiceProvider with the new one

//Illuminate\Mail\MailServiceProvider::class,
\App\Mail\Transports\MailServiceProvider::class,

Add 'zone' to config/service.php

    'mailgun' => [
        'domain' => env('MAILGUN_DOMAIN'),
        'secret' => env('MAILGUN_SECRET'),
        'zone' => env('MAILGUN_ZONE', 'USA'),
    ],

And finally in your .env file add
MAILGUN_ZONE=EU

Might not be the best way to solve the issue, but it's working for me.

See #25010 as well.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

ghost picture ghost  路  3Comments

fideloper picture fideloper  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments

Anahkiasen picture Anahkiasen  路  3Comments