Laravel
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.