Problem Statement
You might come across to the situation where you need to test your email configuration in your Laravel application - in my case, I need to test the:
- SMTP Connection
- Send E-mail using Queue
- Send E-mail not using Queue
I don't want to test my e-mail by having to go through entire process of my application functions.
I'm simply want to tackle above 3 use cases.
Solution
So, let's create an artisan command that be able to send e-mail either using queue or not.
Mail Class
First thing first, let's create a Mail class:
php artisan make:mail DefaultMail
And I have the following class, which I added a bit of customisation on constructor and few other things.
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class DefaultMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
public string $title,
public $message,
public ?string $url = null,
public $attachment = null
) {
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: $this->title,
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.default',
with: [
'title' => $this->title,
'content' => $this->message,
'url' => $this->url,
],
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
if (empty($this->attachment) || ! file_exists($this->attachment)) {
return [];
}
return [
Attachment::fromPath($this->attachment),
];
}
}
The view:
@component('mail::message')
{{ __('Hi') }},
<p style="text-align: justify">
@foreach($message as $msg)
<span style="text-align: justify">
{!! $msg !!}
</span>
@endforeach
</p>
@if(isset($url) && !empty($url) )
@component('mail::button', ['url' => $url])
{{ (isset($url_text) && !empty($url_text)) ? $url_text : __('Click here') }}
@endcomponent
@endif
{{ __('Thanks') }},<br>
{{ config('app.name') }}
@endcomponent
Artisan Command
Next, let's create an artisan command:
php artisan make:command TestSendEmailCommand
Then I have the following in the class:
<?php
namespace App\Console\Commands;
use App\Mail\DefaultMail;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
class TestSendEmailCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:test {email} {--queue= : Type of queue - default, mail, notification}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Send test email';
/**
* Execute the console command.
*/
public function handle()
{
$email = new DefaultMail('Test Email', 'This is a test email');
if ($this->option('queue')) {
Mail::to($this->argument('email'))
->queue(
$email->onQueue($this->option('queue'))
);
} else {
Mail::to($this->argument('email'))->send($email);
}
}
}
Now your artisan command are ready to be test.
Test Sending E-mail
The first test is to send without queue:
php artisan email:test your@email.com
You should receive the e-mail almost immediately.
Next, sending out e-mail to using queue.
Please make sure you have queue running - either using Horizon or run the queue:work command.
php artisan email:test your@email.com --queue=mail
From queue, it might delayed a little bit, depends on your queue processing.
Summary
With this approach, you can test the mail configuration even in production.
You don't have to go through the application entire process to test the e-mail configuration.
Another note, we can confirm easily with operation / support team in case they saying e-mail didn't get send to users, by testing first the connectivity to the SMTP server.
This helped reduced time to debug the SMTP connectivity.
Credits
Photo by Joanna Kosinska on Unsplash
Top comments (0)