Install pusher

composer require pusher/pusher-php-server

Add environment variables

PUSHER_HOST=//not needed

Make sure you change the Broadcast driver to pusher


Go to “config/app.php” and uncomment the following line:


Create an Event

php artisan make:event MessageReceived

Inside of Event class


namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageReceived implements ShouldBroadcast
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;
    public $account_id;
    public $conversation_id;

     * Create a new event instance.
     * @return void
    public function __construct($account_id, $conversation_id, $message)
        $this->message = $message;
        $this->account_id = $account_id;
        $this->conversation_id = $conversation_id;

     * Get the channels the event should broadcast on.
     * @return \Illuminate\Broadcasting\Channel|array
    public function broadcastOn()
        return new PrivateChannel('account.' . $this->account_id);

    public function broadcastAs()
        return 'message-received';

Create endpoint for Pusher to authenthicate with Laravel Passport

 * Authenticates logged-in user in the Pusher JS app
 * For private channels
 * @throws PusherException
public function pusherAuth(Request $request)
    parse_str($request->getContent(), $output);

    $user = auth()->user();

    if($output['channel_name'] !== 'private-account.' . $user->account_id){
        return response([
            'message' => 'Not authorized to access this channel'
        ], 403);
    $key = env('PUSHER_APP_KEY');
    $secret = env('PUSHER_APP_SECRET');
    $app_id = env('PUSHER_APP_ID');
    if ($user) {
        $pusher = new Pusher($key, $secret, $app_id);
        $auth = $pusher->authorizeChannel($output['channel_name'], $output['socket_id']);
        return response($auth, 200);
    } else {
        return response([
            'message' => 'Not authorized to access this channel'
        ], 403);

Add route to function created above

Route::post('pusher', [AuthController::class, 'pusherAuth']);

Have Javascript subscribe to an account channel.

Import the library

<script src=""></script>


var pusher = new Pusher('{{PUSHER_KEY}}', {
  cluster: 'mt1',
  broadcaster: 'pusher',
  channelAuthorization: {
    endpoint: '{{API_ENDPOINT}}auth/pusher',//to endpoint created above
    forceTLS: false,
    encrypted: true,
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer {{BEARER_TOKEN}}'

var channel = pusher.subscribe('private-account.{{ACCOUNT_UUID}}');
channel.bind('message-received', function (data) {//needs to be the same as the broadcast as

Send a message

event(new MessageReceived($conversation->account_id, $conversation->conversation_id, $request->Body));

REMEMBER: Events in Laravel are broadcast with the default queue configuration. If you have horizon installed in your application, then you need to run horizon to trigger the events.


  • If the front end is not calling the authentication endpoint:
    • Check that the cluster matches the application key used. For some reason it won’t throw an error, it will just fail silently and just not call the authentication endpoint.

Leave a Reply

Your email address will not be published. Required fields are marked *