Laravel gebruikt Sendmail met Postfix en een Fallback – aangepaste mailer

Er zijn momenten waarop u liever sendmail gebruikt in plaats van diensten als Mailgun, gezien de prijzen.

Wanneer u bijvoorbeeld een VPS bestelt bij TransIP, krijgt u op dit moment 1000 gratis mails.

Helaas ondersteunt Laravel's fallback het niet als Postfix down is. Daarom heb ik + GPT deze custom mailer geschreven.

Maak een bestand met de naam App\Mail\ConditionalTransport.php:

php
<?php

namespace App\Mail;

use Illuminate\Mail\MailManager;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mailer\Transport\AbstractTransport;

class ConditionalTransport extends AbstractTransport
{
    protected $sendmailTransport;
    protected $mailgunTransport;
    protected $cacheKey;

    /**
     * Create a new Conditional transport instance.
     */
    public function __construct(MailManager $mailManager)
    {
        parent::__construct();

        $this->cacheKey = 'email_sendmail_count_' . date('Y-m-d');

        // Create the sendmail transport
        $this->sendmailTransport = $mailManager->createSymfonyTransport(['transport' => 'sendmail']);

        // Create the mailgun transport
        $this->mailgunTransport = $mailManager->createSymfonyTransport(['transport' => 'mailgun']);
    }

    /**
     * Send the given message.
     *
     * @param \Symfony\Component\Mailer\SentMessage $message
     */
    protected function doSend(SentMessage $message): void
    {
        // Check if Postfix service is running
        if ($this->isPostfixRunning()) {
            // Get the current count from cache
            $count = Cache::get($this->cacheKey, 0);

            if ($count < 1000) {
                // Send with Sendmail
                $this->sendmailTransport->send($message->getOriginalMessage(), $message->getEnvelope());

                // Increment the count
                Cache::increment($this->cacheKey);
                return;
            }
        }

        // If Postfix is not running or count >= 2000, send with Mailgun
        $this->mailgunTransport->send($message->getOriginalMessage(), $message->getEnvelope());
    }

    /**
     * Check if Postfix service is running.
     *
     * @return bool
     */
    protected function isPostfixRunning(): bool
    {
        $isDisabled = in_array('exec', explode(',', ini_get('disable_functions')));

        if ($isDisabled) {
            // If exec is disabled, we can't check; assume it's not running
            return false;
        }

        try {
            $output = [];
            $returnVar = null;
            exec('systemctl is-active postfix', $output, $returnVar);

            if (isset($output[0]) && trim($output[0]) === 'active') {
                return true;
            }
        } catch (\Exception $e) {
            // Handle exception or log error if necessary
        }

        return false;
    }

    /**
     * Get the string representation of the transport.
     */
    public function __toString(): string
    {
        return 'conditional';
    }
}

Registreer vervolgens uw aangepaste transport binnen de opstartmethode van uw applicatie App\Providers\AppServiceProvider dienstverlener:

php gebruik App\Mail\ConditionalTransport; gebruik Illuminate\Mail\MailManager; gebruik Illuminate\Support\Facades\Mail; /** * Bootstrap alle applicatieservices. */ public function boot(): void { Mail::extend('conditional', function (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }

Voeg vervolgens een nieuwe mailerdefinitie toe aan de map van uw toepassing. configuratie/mail.php configuratiebestand dat gebruikmaakt van het nieuwe transport:

php 'mailers' => [ // Andere mailers... 'conditional' => [ 'transport' => 'conditional', ], ],

Met deze instelling gebruikt uw Laravel-applicatie de sendmail-driver om e-mails te versturen als de Postfix-service actief is en de dagelijkse limiet nog niet is bereikt. Zodra de limiet wordt overschreden of als Postfix niet actief is, schakelt deze automatisch over naar de Mailgun-driver.

Opmerkingen:

  • De isPostfixRunning methode controleert of de Postfix-service actief is met behulp van de uitvoerend functie om te bellen systemctl is-actief postfixPas deze methode aan als uw omgeving een andere manier gebruikt om services te beheren of als exec is uitgeschakeld.
  • Het aantal e-mails wordt gecached met behulp van Laravel's Cache-facade met een sleutel die de huidige datum bevat (met behulp van de Ymd-indeling).
  • Zorg ervoor dat uw sendmail- en mailgun-configuraties correct zijn ingesteld in uw configuratie/mail.php bestand.

Deze implementatie is in overeenstemming met de documentatie van Laravel over aangepaste transporten en zou naadloos in uw toepassing moeten passen.

Mailgun wordt als alternatief geselecteerd, maar u kunt ook andere drivers opgeven als u dat wenst.

Momenteel is de limiet 1000 verzendingen per dag, maar u kunt dit naar eigen wens aanpassen.

Getest met Laravel 10. Gebruik op eigen risico, uiteraard :).

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

nl_NLNederlands
Scroll naar boven