Polymorphic conversations (chatrooms) with messages and participants for Laravel applications.
A conversation is a room. Any party can join as a participant (a customer Contact, a User/agent, a bot, the system) and any party can post a message. A conversation can optionally be about something (a support request, an order, a deal) through a polymorphic conversable link, and every conversation is scoped to a polymorphic owner (your tenant) via whilesmart/eloquent-owner-access.
The package is channel-agnostic. It stores and serves conversations, messages, and participants and emits domain events. Delivering a message over WhatsApp, email, or SMS is the host application's job: listen for MessageCreated and dispatch through your own driver.
composer require whilesmart/eloquent-conversations
php artisan migrate| Model | What it is |
|---|---|
Conversation |
The room. Has an owner (tenant), an optional conversable (what it is about), a channel, a status, and last_message_at. |
Message |
A single message in a room. Has a polymorphic author (any party), a direction (inbound/outbound), a type (text/note/event), body, attachments, and an external_id for provider dedupe. |
ConversationParticipant |
A member of the room. Polymorphic participant, a role, and last_read_at for read receipts. |
All routes are registered under the configured prefix (default api) and middleware (default ['api','auth:sanctum']). Set conversations.register_routes to false to supply your own controllers.
| Method | Path | Action |
|---|---|---|
| GET | /conversations |
List (owner-scoped; filter by status, channel, conversable_*) |
| POST | /conversations |
Create a room |
| GET | /conversations/{conversation} |
Show with messages + participants |
| PUT | /conversations/{conversation} |
Update (status, subject, ...) |
| DELETE | /conversations/{conversation} |
Soft delete |
| GET | /conversations/{conversation}/messages |
List the thread |
| POST | /conversations/{conversation}/messages |
Post a message |
| GET | /conversations/{conversation}/participants |
List participants |
| POST | /conversations/{conversation}/participants |
Add a participant (idempotent) |
| POST | /conversations/{conversation}/read |
Mark read for the calling user |
use Whilesmart\Conversations\Traits\HasConversations; // on a Request, Order, Deal...
use Whilesmart\Conversations\Traits\ParticipatesInConversations; // on a User, Contact...ConversationCreated, MessageCreated, ParticipantJoined. These are plain events (not broadcast). Bridge them in your app to broadcast over websockets or trigger channel delivery.
Publish the config to override models, table names, UUID mode, and route registration:
php artisan vendor:publish --tag=conversations-configcomposer test
composer pint:test