Weave 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

rtippin/messenger

Laravel Messenger adds a complete messaging system to your app: private and group conversations, real-time broadcasts, attachments, reactions, read receipts, and notifications. Eloquent-driven, customizable, and easy to integrate with any Laravel project.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal path from zero to a working private thread:

  1. Install the package

    composer require rtippin/messenger
    php artisan messenger:setup
    

    messenger:setup publishes the config, migrations, and frontend assets and runs migrations. If you prefer manual control, publish the individual tags:

    php artisan vendor:publish --tag=messenger.config
    php artisan vendor:publish --tag=messenger.migrations
    php artisan vendor:publish --tag=messenger.assets
    php artisan migrate
    
  2. Make your authenticatable model a messenger provider

    Add the trait and implement the contract on App\Models\User:

    use RTippin\Messenger\Contracts\Messenger;
    use RTippin\Messenger\Traits\HasMessenger;
    
    class User extends Authenticatable implements Messenger
    {
        use HasMessenger;
    }
    
  3. Register the provider in config/messenger.php

    Add your model and its morph alias under providers:

    'providers' => [
        App\Models\User::class => 'user',
    ],
    

    If you use multiple provider models (e.g. User, Team), register each one and enforce a matching morph map.

  4. Configure broadcasting and a queue worker

    Real-time messaging is delivered through Laravel broadcasting events:

    BROADCAST_CONNECTION=reverb
    QUEUE_CONNECTION=redis
    
    php artisan queue:work
    
  5. First use case: create a private thread and send a message

    use RTippin\Messenger\Facades\Messenger as MessengerFacade;
    
    $thread = MessengerFacade::threads()->create(
        [
            'owner_id'   => $user->id,
            'owner_type' => $user->getMorphClass(),
            'type'       => 'private',
        ],
        [
            $other->id => $other->getMorphClass(),
        ]
    );
    
    MessengerFacade::messages()->send($thread, $user, 'Hello!');
    

    Listen on the client with Echo:

    Echo.private(`messenger.thread.${threadId}`)
        .listen('.message.created', (e) => {
            console.log(e.message);
        });
    

The package also ships API routes (default prefix /api/messenger) protected by auth, so a SPA can use HTTP endpoints instead of the facade.

Implementation Patterns

  • Facade for backend workflows, API for frontend workflows. Use Messenger::threads(), Messenger::messages(), Messenger::participants(), and Messenger::calls() for server-side operations (seeders, bots, admin panels). Use the package’s HTTP routes from your SPA or mobile client so you inherit the package’s authorization, validation, and broadcast behavior.

  • Private vs group threads. Threads are created with a type of private or group. A private thread takes exactly one other participant; a group thread takes an array of participants and optional name, avatar, and invite settings. Creation through the facade is:

    Messenger::threads()->create($attributes, [
        $participant->id => $participant->getMorphClass(),
    ]);
    
  • Message composition. Text, replies, attachments, and reactions are handled separately:

    1. Upload attachments first (the package exposes file upload endpoints and stores them on the configured disk).
    2. Send the message with the body and any file IDs / reply target.
    3. Reaction endpoints or Messenger::messages()->react(...)-style calls add emoji reactions.

    Keep uploads and message sends in separate requests so failed uploads do not create empty messages.

  • Bots are scheduled, not automatic. Implement the MessengerBot contract, register the bot class in config/messenger.php under bots, then schedule the bot command:

    // app/Console/Kernel.php or routes/console.php
    $schedule->command('messenger:bots')->everyMinute();
    

    Bots are useful for welcome messages, moderation, canned responses, and thread automation. They only run when the command is scheduled and the queue worker is running.

  • Real-time integration. The package broadcasts events such as message.created, message.reaction, and call signaling events on private channels like messenger.thread.{threadId}. Listen with Echo and update local state from the event payloads rather than re-fetching the whole thread after every message.

  • Calls use WebRTC signaling. Configure STUN/TURN servers in config/messenger.php, then use the package’s call endpoints and listen for call events on the thread channel. The package handles signaling; you still need a TURN server for reliable production calls.

  • Authorization hooks. The package checks thread participation and the authenticated Messenger provider. Add domain rules through Laravel gates/policies and the package’s events rather than editing vendor code. For example, gate group creation or restrict who can add participants.

  • Extension points. Prefer:

    • Extending package models and swapping them in config.
    • Listening to RTippin\Messenger\Events\* for auditing, notifications, or integrations.
    • Disabling built-in routes and writing custom controllers if your app needs a different API shape.
    • Using the package’s testing helpers to fake the authenticated provider in feature tests.

Gotchas and Tips

  • Missing trait or contract breaks everything. If your User model does not use HasMessenger and implement Messenger, thread creation and provider resolution fail. This is the most common setup mistake.

  • Morph map mismatch. If you use Relation::enforceMorphMap(), the morph aliases must match the aliases registered in config/messenger.php. A mismatch causes participants to be stored with one type and queried with another.

  • Clear config cache after editing providers or bots. config/messenger.php is cached in production. Run php artisan config:clear after adding a bot or provider; otherwise the package will not see it.

  • Broadcasting silently does nothing without a queue worker. The events implement ShouldBroadcast; if your queue is not running or is misconfigured, messages persist but clients never receive them. Check BROADCAST_CONNECTION, QUEUE_CONNECTION, and the channel authorization callback.

  • Channel authorization uses the default broadcast auth route. Ensure Broadcast::routes(['middleware' => ['web', 'auth']]) is registered and that your Echo client authenticates with the same session/CSRF setup.

  • Migration conflicts. The package publishes threads, messages, participants, and related tables. If your app already has tables with those names, rename the package tables in config or use a table prefix before running migrations.

  • Attachment disk defaults. The default attachment disk is often public. For private files, switch to s3 or a private disk and verify signed URL generation. Also configure max upload size and image dimensions; large uploads otherwise fail at the PHP/web-server level rather than with a clear validation error.

  • Bots need both scheduling and a queue. Scheduling messenger:bots without a running queue worker means bot actions are dispatched but never processed. Start with QUEUE_CONNECTION=sync in local development if you want immediate execution, then move to Redis/database in production.

  • Calling needs TURN for production. The default STUN configuration is fine for local testing but will fail for users behind symmetric NATs. Configure a TURN server before shipping calling features.

  • Use events instead of modifying vendor code. Listen to package events for notifications, analytics, and integrations. This keeps upgrades safe and avoids forking the package.

  • Rate-limit and throttle the API routes. Messenger endpoints can create threads, upload files, and send messages. Add throttle middleware to config('messenger.routes.middleware') or your route group to prevent abuse.

  • Frontend assets are optional. The package ships assets for its own UI, but the API is usable headlessly. If you are building a custom frontend, you can skip asset publishing and consume the JSON endpoints directly.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package