*/ public array $backoff = [30, 120, 300]; public function __construct( public readonly string $emailLogId, public readonly EmailTemplateType $type, public readonly string $recipientEmail, public readonly string $recipientName, public readonly array $template, public readonly array $branding, public readonly ?string $actionUrl = null, ) { $this->onQueue('emails'); } public function handle(): void { $emailLog = EmailLog::find($this->emailLogId); // Idempotency: don't re-send if already sent or missing if (! $emailLog || $emailLog->status === EmailLogStatus::SENT) { return; } try { $mailable = new TransactionalMail( template: $this->template, branding: $this->branding, actionUrl: $this->actionUrl, ); if ($this->branding['reply_to_email']) { $mailable->replyTo( $this->branding['reply_to_email'], $this->branding['reply_to_name'], ); } Mail::to($this->recipientEmail, $this->recipientName) ->send($mailable); $emailLog->update([ 'status' => EmailLogStatus::SENT->value, 'sent_at' => now(), ]); } catch (\Exception $e) { $emailLog->update([ 'status' => EmailLogStatus::FAILED->value, 'failed_at' => now(), 'error_message' => Str::limit($e->getMessage(), 500), ]); throw $e; } } }