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 avexec
funktion att ringasystemctl ä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 :).