Kevin
Kevin

Reputation: 62

How do you send a templated Mailgun email with Laravel?

I'm trying to figure out if there's a way to send a Mailgun template through a Laravel mailable.

The following code sends my email fine using a blade view:

return $this->from(['address'=>'[email protected]', 'name'=>'Domain'])
        ->subject("subject")
        ->replyTo(['address'=>'[email protected]'])
        ->view('emails.deliverReport')
        ->withSwiftMessage(function($message){
            $headers = $message->getHeaders();
            $headers->addTextHeader("X-Mailgun-Variables", '{"type": "asset-delivery"}');
            $headers->addTextHeader("X-Mailgun-Tag", "asset-delivery");
        });

I'd like to send a template that I've created on Mailgun as opposed to using a blade template.

You are able to do this with CURL by sending the template as form data:

curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Sender Bob <sbob@YOUR_DOMAIN_NAME>' \
-F to='[email protected]' \
-F subject='Hello' \
-F template='template.test' \
-F h:X-Mailgun-Variables='{"title": "API documentation", "body": "Sending messages with templates"}'

Has anyone had any luck sending a Mailgun template via a Laravel mailable?

Upvotes: 2

Views: 1011

Answers (1)

Moritz Friedrich
Moritz Friedrich

Reputation: 1481

Most probably this doesn't concern you anymore, but it answers the question. I've created a library that adds a new notification channel to send templated messages to Laravel; this breaks down to something like the following:

  1. Create a new channel:

    class MailgunTemplatesChannel
    {
        public function __construct(private Mailgun $mailgun)
    
        public function send($notifiable, Notification $notification): void
        {
            [$template, $params] = $notification->toMailgun($notifiable);
    
            // Route the notification to the mail recipient address
            $params['to'] = $notifiable->routeNotificationFor('mail');
    
            $this->mailgun->messages()->send([
                'template' => $template,
                ...$params,
            ]);
        }
    }
    
  2. Setup Mailgun and register the channel in a service provider:

    class AppServiceProvider extends ServiceProvider
        public function register(): void
        {
            // ...
    
            // Configure Mailgun
            $this->app->bind(Mailgun::class, fn() => Mailgun::create(
                config('services.mailgun.secret'),
                config('services.mailgun.endpoint', 'https://api.mailgun.net'),
            ));
    
            // Register the channel
            Notification::resolved(fn(ChannelManager $service) => $service->extend(
                'mailgun', // This is the notification channel identifier
                fn(Application $app) => $app->make(MailgunTemplatesChannel::class)
            ));
        }
    
  3. Configure notifications to send via the new Mailgun channel:

    class MyTestNotification extends Notification
    {
        public function toMailgun(): array
        {
            return [ 
                'subject' => 'Your subject',
                'template' => 'name_of_the_template',
                'v:some_variable' => 'a template variable value',
            ];
        }
    
        public function via(): array
        {
            return [ 'mailgun' ];
        }
    }
    
  4. Send notifications via Mailgun:

    $user->notify(new MyTestNotification());
    

Please don't just copy-paste this into your app! It's a rough outline of how to build a custom channel for templated messages, but it leaves a lot to desire.
If you want a production-ready package, take a look at matchory/laravel-mailgun-templates-channel.

Upvotes: 0

Related Questions