Search code examples
dkimlaravel-9symfony-mailer

How to sign outgoing emails in Laravel 9 with a DKIM signature


Please explain conception how to sign outgoing emails in Laravel 9 with a DKIM signature. Laravel 9 uses Symfony mailer. I'm trying to proceed by this way:

class ContactForm extends Mailable
{
    use Queueable, SerializesModels;

    public $mailData;

    public function __construct($mailData)
    {
        $this->mailData = $mailData;
    }

    public function build()
    {
        $this->subject($this->mailData['subject'])
            ->view('mail.contact-form')
            ->text('mail.contact-form_plain');

        $this->withSymfonyMessage(function (Email $message) {
            $signer = new DkimSigner(config('mail.dkim_private_key'), config('mail.dkim_domain'),
            config('mail.dkim_selector'));
            $signer->sign($message);
        });

        return $this;
    }
}

Error

local.ERROR: A message must have a text or an HTML part or attachments. {"exception":"[object] (Symfony\Component\Mime\Exception\LogicException(code: 0): A message must have a text or an HTML part or attachments. at E:\WebProjects\domains\hostbrook\vendor\symfony\mime\Email.php:390)


Solution

  • There is other way to sign outgoing emails in Laravel 9 with a DKIM signature (without any tool):

    class ContactForm extends Mailable
    {
        use Queueable, SerializesModels;
    
        public $mailData;
    
        public function __construct($mailData)
        {
            $this->mailData = $mailData;
        }
    
        public function build()
        {
            $mailData = $this->mailData;
    
            $htmlView = 'mail.contact-form';
            $plainView = 'mail.contact-form_plain';
    
            $htmlEmail = view($htmlView, compact('mailData'))->render();
            $plainEmail = view($plainView, compact('mailData'))->render();
    
            return $this->subject($this->mailData['subject'])
                ->view($htmlView)
                ->text($plainView)
                ->withSymfonyMessage(function (Email $message) use ($htmlEmail, $plainEmail) {
                    $message
                        ->html($htmlEmail)
                        ->text($plainEmail);
    
                    $signer = new DkimSigner(
                        config('mail.dkim_private_key'),
                        config('mail.dkim_domain'),
                        config('mail.dkim_selector')
                    );
    
                    $signedEmail = $signer->sign($message);
    
                    $message->setHeaders($signedEmail->getHeaders());
                });
        }
    }