grunt fokus fotografi av grå brevlåda

Laravel använder Sendmail med Postfix och en Fallback – anpassad mailer

Det finns tillfällen då du skulle vilja använda sendmail istället för tjänster som Mailgun, med tanke på deras prissättning.

Till exempel, när du beställer en VPS hos TransIP kommer de att ge dig 1000 gratis e-postmeddelanden i skrivande stund.

Tyvärr stöder inte Laravels fallback det när Postfix är nere. Det är därför jag + GPT skrev detta anpassade brev.

Skapa en fil med namnet 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';
    }
}

Registrera sedan din anpassade transport inom uppstartsmetoden för din applikation App\Providers\AppServiceProvider tjänsteleverantör:

php använd App\Mail\ConditionalTransport; använd Illuminate\Mail\MailManager; använd Illuminate\Support\Facades\Mail; /** * Bootstrap alla applikationstjänster. */ public function boot(): void { Mail::extend('villkorlig', funktion (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }

Lägg sedan till en ny mailerdefinition till din applikation config/mail.php konfigurationsfil som använder den nya transporten:

php 'mailers' => [ // Andra utskick... 'conditional' => [ 'transport' => 'villkorlig', ], ],

Med den här inställningen kommer din Laravel-applikation att använda sendmail-drivrutinen för att skicka e-post om Postfix-tjänsten körs och den dagliga gränsen inte har nåtts. När gränsen överskrids eller om Postfix inte körs kommer den automatiskt att växla till Mailgun-drivrutinen.

Anmärkningar:

  • De är PostfixRunning metod kontrollerar om Postfix-tjänsten körs med hjälp av exec funktion att ringa systemctl är aktiv postfix. Justera den här metoden om din miljö använder ett annat sätt att hantera tjänster eller om exec är inaktiverat.
  • Antalet e-postmeddelanden cachas med hjälp av Laravels Cache-fasad med en nyckel som inkluderar det aktuella datumet (med Ymd-formatet).
  • Se till att dina sendmail- och mailgun-konfigurationer är korrekt inställda i din config/mail.php fil.

Denna implementering följer Laravels dokumentation om anpassade transporter och bör passa sömlöst in i din applikation.

Den väljer Mailgun som ett alternativ, men du kan också ange andra drivrutiner om du vill.

Den har för närvarande en gräns på 1000 sändningar per dag, men ändra den till din egen önskade frekvens.

Testad med Laravel 10. Används på egen risk såklart :).

Lämna en kommentar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

sv_SESvenska
Bläddra till toppen