Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Messenger Laravel Package

cmgmyr/messenger

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation

    composer require cmgmyr/messenger
    php artisan vendor:publish --provider="Cmgmyr\Messenger\MessengerServiceProvider" --tag="migrations"
    php artisan migrate
    
    • Run migrations to create messages and message_recipients tables.
  2. Basic Setup

    • Publish config (optional):
      php artisan vendor:publish --provider="Cmgmyr\Messenger\MessengerServiceProvider" --tag="config"
      
    • Configure config/messenger.php (e.g., default sender, message TTL).
  3. First Use Case: Sending a Message

    use Cmgmyr\Messenger\Models\Message;
    use Cmgmyr\Messenger\Models\Recipient;
    
    // Create a message
    $message = Message::create([
        'subject' => 'Welcome!',
        'body' => 'Thanks for signing up!',
        'sender_id' => auth()->id(), // or a default sender
    ]);
    
    // Assign recipients (users or models with `recipient_id`)
    $message->recipients()->attach([1, 2, 3]); // User IDs
    // OR for non-user models:
    // $message->recipients()->attach([new Recipient(['recipient_id' => 123, 'recipient_type' => 'Order'])]);
    
  4. Viewing Messages

    • Use the hasUnreadMessages() helper or query the messages table directly:
      $unread = auth()->user()->unreadMessages()->count();
      

Implementation Patterns

Core Workflows

  1. Sending Messages

    • Bulk Sending:
      $message = Message::create(['subject' => 'Newsletter', 'body' => '...']);
      $message->recipients()->sync($userIds); // Replace all recipients
      
    • Delayed Messages (via Laravel Queues):
      $message = Message::create(['subject' => 'Later', 'body' => '...']);
      dispatch(new \Cmgmyr\Messenger\Jobs\SendMessage($message))->delay(now()->addHours(1));
      
  2. Reading/Marking Messages

    • Mark as read (for current user):
      auth()->user()->messages()->update(['read_at' => now()]);
      
    • Soft-delete messages:
      $message->delete(); // Uses Laravel's soft deletes
      
  3. Customizing Recipients

    • Extend Recipient model for non-user entities (e.g., Order):
      class OrderRecipient extends Recipient {
          protected $recipientType = 'Order';
      }
      
    • Attach dynamically:
      $message->recipients()->attach(
          new OrderRecipient(['recipient_id' => $order->id])
      );
      
  4. Notifications Integration

    • Trigger notifications when messages are sent/received:
      $message->save();
      $message->recipients->each->notify(new \App\Notifications\NewMessage($message));
      
  5. API Endpoints

    • Example routes (routes/api.php):
      Route::middleware('auth:sanctum')->group(function () {
          Route::get('/messages', [MessageController::class, 'index']);
          Route::post('/messages/{message}/read', [MessageController::class, 'markAsRead']);
      });
      

Integration Tips

  • Laravel Notifications: Use Messenger alongside notifications for multi-channel delivery (e.g., email + in-app).
  • Search: Add a scout driver to Message model for full-text search:
    use Laravel\Scout\Searchable;
    class Message extends Model {
        use Searchable;
    }
    
  • Webhooks: Extend Message events to trigger external services:
    // In EventServiceProvider
    protected $listen = [
        \Cmgmyr\Messenger\Events\MessageSent::class => [
            \App\Listeners\SendSlackAlert::class,
        ],
    ];
    

Gotchas and Tips

Pitfalls

  1. Recipient Type Mismatches

    • Ensure recipient_type matches the model's class name (e.g., 'User' for App\Models\User).
    • Fix: Use getMorphClass() or explicitly set recipient_type when attaching.
  2. Memory Issues with Large Recipient Lists

    • Attaching thousands of recipients at once may cause timeouts.
    • Fix: Use chunking:
      $recipients->chunk(500)->each(function ($chunk) use ($message) {
          $message->recipients()->attach($chunk->pluck('id'));
      });
      
  3. Soft Deletes Confusion

    • delete() soft-deletes messages but leaves recipients intact.
    • Fix: Use purge() to fully remove:
      $message->delete(); // Soft delete
      $message->forceDelete(); // Hard delete
      
  4. Default Sender Overrides

    • If config('messenger.default_sender') is set, it overrides sender_id on creation.
    • Fix: Pass ['sender_id' => null] to bypass defaults.
  5. Event Ordering

    • MessageSent fires after recipients are attached, so avoid logic that assumes recipients exist in the event handler.

Debugging

  • Check Recipient Attachments:
    $message->recipients->load('user'); // Eager-load relationships
    
  • Log Failed Sends:
    \Cmgmyr\Messenger\Events\MessageSent::dispatch($message);
    // Add a listener to log errors
    
  • Query Recipient Issues:
    SELECT * FROM message_recipients WHERE recipient_id IS NULL;
    

Extension Points

  1. Custom Message Models

    • Extend Message to add fields (e.g., priority, template_id):
      class CustomMessage extends Message {
          protected $casts = ['priority' => 'integer'];
      }
      
    • Update migrations/policies accordingly.
  2. Recipient Validation

    • Override validateRecipient() in a custom Recipient model:
      public static function validateRecipient($recipientId, $recipientType) {
          return Model::where('id', $recipientId)->where('active', 1)->exists();
      }
      
  3. Message Templates

    • Store templates in the DB and render them dynamically:
      $template = MessageTemplate::find(1);
      $message = Message::create([
          'subject' => $template->subject,
          'body' => view('messages.template', ['data' => $vars])->render(),
      ]);
      
  4. Rate Limiting

    • Use Laravel middleware to limit message frequency:
      Route::middleware(['throttle:10,1'])->group(function () {
          Route::post('/messages', [MessageController::class, 'store']);
      });
      
  5. Testing

    • Mock the Messenger facade or use partialMock:
      $this->partialMock(Message::class, function ($mock) {
          $mock->shouldReceive('create')->andReturn($fakeMessage);
      });
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope