roundly-consulting/messages-for-laravel
Messages for Laravel provides a clean, simple API for composing, queuing, and delivering messages within your Laravel application. It supports multiple channels and customizable templates, streamlining in-app and user-to-user communication with minimal setup.
Start by publishing the package config/migrations and running migrations, then locate the messaging config and resource classes. The first file to inspect is config/messages.php, specifically messages.resources.participant, which now defaults to MessageParticipantResource::class.
First practical use case: render a message thread through MessageResource and let participants/senders render through MessageParticipantResource. If your models implement ParticipatesInMessaging, the default resource uses participateAs(); otherwise it emits a simple {id, type} object.
Key classes to review first:
MessageResource — message payload, including sender and reply_to.sender_type.ParticipantResource — participant payload.MessageParticipantResource — new default participant/sender resource.NewMessageNotification — database and broadcast notification payloads.For a quick start, send a message between two models, return MessageResource from a controller, and inspect the JSON. Then decide whether the default {id, type} participant shape is enough or whether you need names/avatars via a custom participant resource.
Use the default resources for standard API responses. MessageResource delegates participant/sender rendering through the configured participant resource, so most apps should customize at that layer rather than overriding message JSON wholesale.
Customize participant output by swapping the config key:
// config/messages.php
'resources' => [
'participant' => App\Http\Resources\ApiParticipantResource::class,
],
Then implement a normal Laravel JsonResource. It receives the participant model:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ApiParticipantResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->getKey(),
'type' => class_basename($this),
'name' => $this->name,
'avatar_url' => $this->avatar_url,
];
}
}
This is the main extension point for adding display names, avatars, profile URLs, or role labels without changing the package internals. If you build resources manually, use MessageParticipantResource::configured($model) to get the configured participant resource around a model.
Keep ParticipatesInMessaging as the source of truth where you already use it. For models implementing that contract, the default resource continues to render participateAs(). If you replace the participant resource, preserve that behavior yourself where needed, for example by branching on the contract or calling participateAs().
For API clients, treat sender and participant as nullable/object-shaped data. A message sender is now rendered as {id, type} for models without ParticipatesInMessaging instead of null, and a participant is null when the participating model no longer exists.
For notifications, verify the database and broadcast payloads if you consume them in a frontend or websocket client. The sender_type value now uses the model class basename rather than the morph type/full class name.
sender, participant, reply_to.sender_type, and notification sender_type.User, not App\Models\User or the morph alias. If clients depended on full class names or morph aliases, switch to a custom participant resource with an explicit stable type contract.null. Code that assumed participant always contained stored IDs should handle null.sender_type values while new ones use basenames. Add fallback handling if you parse historical notifications.messages-resources or messages-notifications stubs, re-publish them or copy the 1.2.0 changes over. Updating the package alone will not update your published copies.JsonResource subclass under messages.resources.participant throws InvalidConfigurationException naming the key. A blank value falls back to the default.php artisan config:clear or rebuild cache in deployment.MessageParticipantResource::configured($model) when debugging resolution. It shows exactly which resource will render a given participant model.id, type, names, and avatar fields stable, and version them if clients cache participant payloads.How can I help you explore Laravel packages today?