How to send Email to Subscribers When You Publish a Post on Laravel
Often we write blog post and wish to send email to subscribers automatically right after the publishing the post. This is a really cool feature for laravel blog application. However it might be tricky. In today’s blog post, I will show you can build a functionalities to send email to subscribers when you publish a post in laravel 10.
What you need?
Table of Content
Scenario
This is my plan as user story:
Scenario: Sending email when a new post is published
- Given I have a list of subscribers
- When I publish a new blog post
- Then all subscribers should receive an email with the new post title and link
Write Code
Let’s write code for that functionalities.
Set environmental values
To set environmental values, lets open our .env
file and set the correct value based on your environment.
.env file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel10
DB_USERNAME=root
DB_PASSWORD=
Set up the controller
I will skip the route set-up. I will jump into the method in the controller which is more important for us.
Assume we have a controller called PostController
where we work with store()
method.
App\Controllers\PostController
use App\Events\PostPublished;
class PostController extends Controller {
public function post(Request $request)
{
// Some form request validation code here
$post = Post::create($request->all());
// Dispatch an event for sending email to subscribers
PostPublished::dispatch($post);
// Other response code...
}
}
ℹ️ Noticed here that, I dispatched an laravel event right after creating the post and passing the $post
object on it.
The main idea is to tell event that something happened in the system, please send the email to all subscriber for that with the right information.
Define an event
To define a new event, I will follow this command.
php artisan make:command PostPublished
Now let’s update the event (just inject the post in the constructor).
class PostPublished
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(public Post $post)
{
}
}
Create the listener
The idea of event-listener is that, once an event is dispatched, a listener need to take care of it. So, let’s create a listener now.
php artisan make:listener SendEmailToSubscribers
class SendEmailToSubscribers
{
public function __construct(public Post $post)
{
}
public function handle(object $event): void
{
}
}
Registering event and listener
Now we need to register event with the respective listener in the boot()
method EventServiceProvider
class.
App\Providers\EventServiceProvider
protected $listen = [
// Some code
PostPublished::class => [
SendEmailToSubscribers::class
]
];
// More code...
Sending email to Subscribers
Now in the handle()
of listener SendEmailToSubscribers
, I want to write code that send email to subscribers.
public function handle(object $event): void
{
// Get Subscribers
// You may need to filter the confirmed subscribers only by confirmed() custom scope.
$subscribers = Subscriber::confirmed()->get();
// Send email to all of them
foreach ($subscribers as $subscriber) {
Mail::to($subscriber->email)
->send(new PublishedNewPost($this->post));
}
}
Create a mailable class
To send an email, let’s create a mailable class, and I want it to markdown.
php artisan make:mail PublishedNewPost --markdown
App\Mail\PublishedNewPost
class PublishedNewPost extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Post $post)
{
}
public function envelope(): Envelope
{
return new Envelope(
subject: $this->post->title
);
}
public function content(): Content
{
return new Content(
markdown: 'mail.published-new-post',
);
}
}
Update mail template (markdown)
resources/mail/published-new-post.blade.php
<x-mail::message>
Hello
The following new post has been published in {{ env('APP_NAME') }}.
{{ $post->title }}
<x-mail::button :url="{{ $post->link() }}">
Give a read now
</x-mail::button>
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>
⚠️ Be aware of that, if you are using any kind of 3rd party server for sending email, they might have email sending limitation per second. You need to find a way to handle that also.
That’s it. It should work fine.