fotografia a fuoco basso di una cassetta postale grigia

Laravel usa Sendmail con Postfix e un Fallback – mailer personalizzato

Ci sono momenti in cui potresti voler usare Sendmail invece di servizi come Mailgun, dati i loro prezzi.

Ad esempio, se ordini un VPS su TransIP, al momento della scrittura riceverai 1000 invii di posta gratuiti.

Sfortunatamente, il fallback di Laravel non lo supporta quando Postfix è inattivo. Ecco perché io + GPT abbiamo scritto questo mailer personalizzato.

Crea un file denominato 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';
    }
}

Successivamente, registra il tuo trasporto personalizzato all'interno del metodo di avvio della tua applicazione App\Provider\AppServiceProvider fornitore di servizi:

php usa App\Mail\ConditionalTransport; usa Illuminate\Mail\MailManager; usa Illuminate\Support\Facades\Mail; /** * Avvia tutti i servizi dell'applicazione. */ public function boot(): void { Mail::extend('conditional', function (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }

Quindi, aggiungi una nuova definizione di mailer alla tua applicazione configurazione/mail.php file di configurazione che utilizza il nuovo trasporto:

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

Con questa configurazione, la tua applicazione Laravel utilizzerà il driver sendmail per inviare email se il servizio Postfix è in esecuzione e il limite giornaliero non è stato raggiunto. Una volta superato il limite o se Postfix non è in esecuzione, passerà automaticamente al driver Mailgun.

Note:

  • IL èPostfixIn esecuzione il metodo verifica se il servizio Postfix è in esecuzione utilizzando esecutivo funzione da chiamare systemctl è-attivo postfissoAdatta questo metodo se il tuo ambiente utilizza un modo diverso per gestire i servizi o se exec è disabilitato.
  • Il conteggio delle email viene memorizzato nella cache utilizzando la facciata Cache di Laravel con una chiave che include la data corrente (utilizzando il formato Ymd).
  • Assicurati che le configurazioni di sendmail e mailgun siano impostate correttamente nel tuo configurazione/mail.php file.

Questa implementazione rispetta la documentazione di Laravel sui trasporti personalizzati e dovrebbe adattarsi perfettamente alla tua applicazione.

Seleziona Mailgun come alternativa, ma puoi anche specificare altri driver se lo desideri.

Attualmente il limite è di 1000 invii al giorno, ma puoi modificarlo in base alla frequenza che preferisci.

Testato con Laravel 10. Ovviamente, usatelo a vostro rischio e pericolo :).

Ultimo aggiornamento il 21 ottobre 2024

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

it_ITItaliano
Scorri verso l'alto