Skip to content

Commit 059b7d6

Browse files
authored
Merge pull request #44 from kirschbaum-development/issue-28-event-notification
ISSUE-28: Implement opt-in notifications for user mentions in comments
2 parents 79fae49 + 4a82ae7 commit 059b7d6

File tree

7 files changed

+342
-5
lines changed

7 files changed

+342
-5
lines changed

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ class SendSubscribedUserNotification implements ShouldQueue
450450

451451
### Sending notifications when a user is mentioned
452452

453-
Every time a user is mentioned, the `Kirschbaum\Commentions\Events\UserWasMentionedEvent` is dispatched. You can listen to this event and send notifications to the mentioned user.
453+
Every time a user is mentioned, the `Kirschbaum\Commentions\Events\UserWasMentionedEvent` is dispatched. Commentions ships an optional, opt-in notification you can enable via configuration, or you can listen to the event and handle it yourself.
454454

455455
Example usage:
456456

@@ -477,6 +477,30 @@ class SendUserMentionedNotification implements ShouldQueue
477477

478478
If you have [event auto-discovery](https://laravel.com/docs/11.x/events#registering-events-and-listeners), this should be enough. Otherwise, make sure to register your listener on the `EventServiceProvider`.
479479

480+
#### Built-in opt-in notifications
481+
482+
Enable notifications for mentions in your `config/commentions.php`:
483+
484+
```php
485+
'notifications' => [
486+
'mentions' => [
487+
'enabled' => true,
488+
'channels' => ['mail', 'database'],
489+
],
490+
],
491+
```
492+
493+
Optionally, provide a URL resolver so emails/links point users to the right place:
494+
495+
```php
496+
use Kirschbaum\Commentions\Config;
497+
498+
Config::resolveCommentUrlUsing(function (\Kirschbaum\Commentions\Comment $comment) {
499+
// Return a URL to view the record and scroll to the comment
500+
return route('projects.show', $comment->commentable) . '#comment-' . $comment->getId();
501+
});
502+
```
503+
480504
### Resolving the authenticated user
481505

482506
By default, when a new comment is made, the `Commenter` is automatically set to the current user logged in user (`auth()->user()`). If you want to change this behavior, you can implement your own resolver:

config/commentions.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,36 @@
4949
// When true, subscribed users will also receive the same event as mentions
5050
// (UserWasMentionedEvent). When false, a distinct
5151
// UserIsSubscribedToCommentableEvent will be dispatched instead.
52-
'dispatch_as_mention' => false,
52+
'dispatch_as_mention' => env('COMMENTIONS_SUBSCRIPTIONS_DISPATCH_AS_MENTION', false),
5353
// Controls whether the subscribers list is shown in the sidebar UI
54-
'show_subscribers' => true,
54+
'show_subscribers' => env('COMMENTIONS_SUBSCRIPTIONS_SHOW_SUBSCRIBERS', true),
5555
// Automatically subscribe the author when they add a comment
56-
'auto_subscribe_on_comment' => true,
56+
'auto_subscribe_on_comment' => env('COMMENTIONS_SUBSCRIPTIONS_AUTO_SUBSCRIBE_ON_COMMENT', true),
5757
// Automatically subscribe a user when they are mentioned in a comment
58-
'auto_subscribe_on_mention' => true,
58+
'auto_subscribe_on_mention' => env('COMMENTIONS_SUBSCRIPTIONS_AUTO_SUBSCRIBE_ON_MENTION', true),
59+
],
60+
61+
/*
62+
|--------------------------------------------------------------------------
63+
| Notifications (opt-in)
64+
|--------------------------------------------------------------------------
65+
|
66+
| Configure notification delivery when a user is mentioned in a comment.
67+
| Disabled by default; enable and choose the channels you want to use.
68+
|
69+
*/
70+
'notifications' => [
71+
'mentions' => [
72+
'enabled' => env('COMMENTIONS_NOTIFICATIONS_MENTIONS_ENABLED', false),
73+
74+
'channels' => explode(',', env('COMMENTIONS_NOTIFICATIONS_MENTIONS_CHANNELS', 'mail')),
75+
76+
'listener' => \Kirschbaum\Commentions\Listeners\SendUserMentionedNotification::class,
77+
'notification' => \Kirschbaum\Commentions\Notifications\UserMentionedInComment::class,
78+
79+
'mail' => [
80+
'subject' => env('COMMENTIONS_NOTIFICATIONS_MENTIONS_MAIL_SUBJECT', 'You were mentioned in a comment'),
81+
],
82+
],
5983
],
6084
];

src/CommentionsServiceProvider.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
use Filament\Support\Assets\Css;
66
use Filament\Support\Assets\Js;
77
use Filament\Support\Facades\FilamentAsset;
8+
use Illuminate\Support\Facades\Event;
89
use Illuminate\Support\Facades\Gate;
910
use Kirschbaum\Commentions\Comment as CommentModel;
11+
use Kirschbaum\Commentions\Events\UserWasMentionedEvent;
12+
use Kirschbaum\Commentions\Listeners\SendUserMentionedNotification;
1013
use Kirschbaum\Commentions\Livewire\Comment;
1114
use Kirschbaum\Commentions\Livewire\CommentList;
1215
use Kirschbaum\Commentions\Livewire\Comments;
@@ -67,5 +70,10 @@ public function packageBooted(): void
6770
$this->publishes([
6871
__DIR__ . '/../resources/lang' => resource_path('lang/vendor/commentions'),
6972
], 'commentions-lang');
73+
74+
if (config('commentions.notifications.mentions.enabled', false)) {
75+
$listenerClass = (string) config('commentions.notifications.mentions.listener', SendUserMentionedNotification::class);
76+
Event::listen(UserWasMentionedEvent::class, $listenerClass);
77+
}
7078
}
7179
}

src/Config.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class Config
1212

1313
protected static ?Closure $resolveAuthenticatedUser = null;
1414

15+
protected static ?Closure $resolveCommentUrl = null;
16+
1517
public static function resolveAuthenticatedUserUsing(Closure $callback): void
1618
{
1719
static::$resolveAuthenticatedUser = $callback;
@@ -39,6 +41,24 @@ public static function getCommentReactionTable(): string
3941
return config('commentions.tables.comment_reactions', 'comment_reactions');
4042
}
4143

44+
public static function resolveCommentUrlUsing(Closure $callback): void
45+
{
46+
static::$resolveCommentUrl = $callback;
47+
}
48+
49+
public static function resolveCommentUrl(?Comment $comment): ?string
50+
{
51+
if ($comment === null) {
52+
return null;
53+
}
54+
55+
if (static::$resolveCommentUrl instanceof Closure) {
56+
return call_user_func(static::$resolveCommentUrl, $comment);
57+
}
58+
59+
return null;
60+
}
61+
4262
public static function getCommentModel(): string
4363
{
4464
return config('commentions.comment.model', Comment::class);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Kirschbaum\Commentions\Listeners;
4+
5+
use Illuminate\Contracts\Queue\ShouldQueue;
6+
use Illuminate\Queue\InteractsWithQueue;
7+
use Illuminate\Support\Facades\Notification;
8+
use Kirschbaum\Commentions\Events\UserWasMentionedEvent;
9+
use Kirschbaum\Commentions\Notifications\UserMentionedInComment;
10+
11+
class SendUserMentionedNotification implements ShouldQueue
12+
{
13+
use InteractsWithQueue;
14+
15+
public function handle(UserWasMentionedEvent $event): void
16+
{
17+
$user = $event->user;
18+
19+
if (! config('commentions.notifications.mentions.enabled', false)) {
20+
return;
21+
}
22+
23+
$channels = (array) config('commentions.notifications.mentions.channels', []);
24+
if (empty($channels)) {
25+
return;
26+
}
27+
28+
$notificationClass = (string) config('commentions.notifications.mentions.notification', UserMentionedInComment::class);
29+
$notification = app($notificationClass, ['comment' => $event->comment, 'channels' => $channels]);
30+
31+
Notification::send($user, $notification);
32+
}
33+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Kirschbaum\Commentions\Notifications;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Contracts\Queue\ShouldQueue;
7+
use Illuminate\Notifications\Messages\BroadcastMessage;
8+
use Illuminate\Notifications\Messages\MailMessage;
9+
use Illuminate\Notifications\Notification;
10+
use Kirschbaum\Commentions\Comment;
11+
use Kirschbaum\Commentions\Config;
12+
use Kirschbaum\Commentions\Manager;
13+
14+
class UserMentionedInComment extends Notification implements ShouldQueue
15+
{
16+
use Queueable;
17+
18+
public function __construct(
19+
protected Comment $comment,
20+
protected array $channels
21+
) {}
22+
23+
public function via(object $notifiable): array
24+
{
25+
return $this->channels;
26+
}
27+
28+
public function toMail(object $notifiable): MailMessage
29+
{
30+
$url = Config::resolveCommentUrl($this->comment) ?? url('/');
31+
32+
return (new MailMessage())
33+
->subject((string) config('commentions.notifications.mentions.mail.subject', 'You were mentioned in a comment'))
34+
->greeting('Hi ' . Manager::getName($notifiable))
35+
->line('You were mentioned in a comment by ' . $this->comment->getAuthorName() . '.')
36+
->line(strip_tags($this->comment->getBodyMarkdown()))
37+
->action('View comment', $url);
38+
}
39+
40+
public function toArray(object $notifiable): array
41+
{
42+
return [
43+
'comment_id' => $this->comment->getId(),
44+
'comment_body' => $this->comment->getBody(),
45+
'author_name' => $this->comment->getAuthorName(),
46+
'url' => Config::resolveCommentUrl($this->comment),
47+
];
48+
}
49+
50+
public function toBroadcast(object $notifiable): BroadcastMessage
51+
{
52+
return new BroadcastMessage($this->toArray($notifiable));
53+
}
54+
}

0 commit comments

Comments
 (0)