phunky / laravel-messaging-reactions
Message reactions extension for phunky/laravel-messaging
Package info
github.com/Phunky/laravel-messaging-reactions
pkg:composer/phunky/laravel-messaging-reactions
Requires
- php: ^8.4
- phunky/laravel-messaging: ^0.0.1
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/boost: ^2.4
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
This package is auto-updated.
Last update: 2026-04-16 15:48:18 UTC
README
Per-message reactions for phunky/laravel-messaging. Each conversation participant can add one reaction per message. Values are plain strings โ emoji, icon slugs (e.g. for Flux <flux:icon>), or any convention your UI uses.
Installation
composer require phunky/laravel-messaging-reactions
Register the extension in config/messaging.php (add to the existing extensions array โ do not remove the core keys):
'extensions' => [ // ... other MessagingExtension classes, if any \Phunky\LaravelMessagingReactions\ReactionsExtension::class, ],
php artisan migrate
Usage
Resolve ReactionService via the container (constructor injection, app(ReactionService::class), etc.):
use Phunky\LaravelMessagingReactions\ReactionService; $reactionService = app(ReactionService::class);
Reacting to a message
// Add or change a reaction โ returns the Reaction model $reaction = $reactionService->react($message, $user, '๐'); // Same value again removes the reaction (toggle) โ returns null $reaction = $reactionService->react($message, $user, '๐'); // A different value replaces the existing reaction $reaction = $reactionService->react($message, $user, 'โค๏ธ');
Each participant has at most one reaction per message (one row per participant, updated in place). Only conversation participants may react โ others throw an exception.
Removing a reaction
// Removes the participantโs current reaction if any; no-op if none $reactionService->removeReaction($message, $user);
Fetching reactions
// Reaction models with participant and messageable eager-loaded $reactions = $reactionService->getReactions($message); // Grouped summary for counts in the UI $summary = $reactionService->getReactionSummary($message); // Each item: ['reaction' => '๐', 'count' => 3, 'participant_ids' => [1, 4, 7]]
Message relationship
Message::reactions() is registered as a hasMany macro โ call it as a method:
$message->reactions()->get(); $message->reactions()->count();
Events
ReactionAdded and ReactionRemoved extend [BroadcastableMessagingEvent](https://github.com/phunky/laravel-messaging) from the core package. They implement ShouldBroadcast and ShouldDispatchAfterCommit, respect config('messaging.broadcasting.enabled'), and use the same private conversation channels as core messaging. With Laravel Echo, listen using the broadcastAs() name with a leading dot (e.g. .listen('.messaging.reaction.added', โฆ)).
| Event | Public properties | broadcastAs() |
|---|---|---|
ReactionAdded |
$reaction, $message, $messageable |
messaging.reaction.added |
ReactionRemoved |
$message, $messageable, $reaction (string) |
messaging.reaction.removed |
ReactionAdded includes the full Reaction model (participant is loaded before dispatch). ReactionRemoved passes the reaction string because the row is already gone.
use Illuminate\Support\Facades\Event; use Phunky\LaravelMessagingReactions\Events\ReactionAdded; Event::listen(ReactionAdded::class, function (ReactionAdded $event) { $event->message->sender?->notify(new \App\Notifications\MessageReacted($event->reaction)); });
License
MIT - see LICENSE.md.