byrcsc/laravel-comments · 1.x
Reply notifications.
The one notification the package ships — when it fires, who it never reaches, how to change its channels and wording, and how to replace it.
The package ships exactly one notification: the author of a comment is told when somebody replies to it. It is off until you say otherwise, because installing a package should never send mail.
Replies are the single comment event with an unambiguous recipient. Watchers, digests, and mentions are yours to build on the events.
Turn it on
COMMENTS_NOTIFY_REPLIES=trueOr in config/comments.php:
'notifications' => [
'reply' => [
'enabled' => true,
'channels' => ['mail'],
],
],channels is the whole delivery story. Set it to ['database'], add your own
channel, and the shipped notification follows without a subclass:
'channels' => ['mail', 'database'],An empty list is a configuration error rather than another way to say off:
enabled is how you say off. Both are validated when the package boots.
When it fires
The trigger is the reply entering the approved set, not its creation:
- A reply that arrives approved notifies at once.
- A reply that arrives pending notifies when a moderator approves it.
- A reply that is rejected or marked as spam never notifies at all.
Nothing here decides what is visible — it reads the same status your own queries do.
At most once per reply, ever
The evidence is reply_notified_at, a column on the reply itself rather than
anything held in memory. An approve, an edit that sends it back to pending, and
a second approval still make one notification.
The marker is written before the send, not after. The send is queued, so a failure downstream is the queue's to retry, while a marker written afterwards would be the one thing a crash could lose — and losing it means notifying twice.
Who is never notified
| Case | Why |
|---|---|
| A guest-authored parent comment | A guest email is unverified input, not a mailbox |
A commentator model without Notifiable | The package will not decide how to route mail |
| Replying to your own comment | You already know |
| A top-level comment | There is no parent author to tell |
The guest rule holds whatever channel is configured. There is no setting that turns it off.
What the mail says
The wording lives in a translation file. Publish it to change or translate it:
php artisan vendor:publish --tag="comments-translations"That writes lang/vendor/comments/en/comments.php. Add a file per locale you
serve.
To restructure the email itself — add a link, change the layout — publish the view:
php artisan vendor:publish --tag="comments-views"That writes resources/views/vendor/comments/mail/reply.blade.php. There is no
link in the shipped mail, because the package owns no routes and has no honest
URL to build. Adding one is the first thing most applications do:
@component('mail::button', ['url' => route('posts.show', $reply->commentable_id)])
Read the reply
@endcomponentEvery string the view interpolates — the bodies, the guest name — is untrusted input, and Blade escapes all of it. Keep it that way.
What the database channel stores
[
'comment_id' => $reply->parent_id,
'reply_id' => $reply->getKey(),
'commentable_type' => $reply->commentable_type,
'commentable_id' => $reply->commentable_id,
]Keys rather than prose, so an application rendering its own notification list is not parsing a sentence back apart.
Replace the notification
To change the message itself rather than its wording, extend the class and bind yours over it in the container:
use ByRcsc\LaravelComments\Notifications\CommentReplied;
$this->app->bind(CommentReplied::class, fn ($app, $params) => new MyReply(
$params['reply'],
));The notification is queued and calls afterCommit() in its constructor. A
comment written in a transaction that rolls back never happened, and mail about
a reply nobody can read is the one failure the at-most-once marker cannot take
back. Keep that if you replace it.
An application without queues runs the sync driver and sends inline, which is what it gets from every other queued notification it owns.
Build your own instead
The reply events fire whether or not the notification is enabled, so an application that wants mentions, watchers, or a digest listens directly:
use ByRcsc\LaravelComments\Events\CommentCreated;
use Illuminate\Support\Facades\Event;
Event::listen(CommentCreated::class, function (CommentCreated $event): void {
if ($event->comment->parent_id !== null) {
// your own routing
}
});Leave comments.notifications.reply.enabled off and nothing competes with you.