How to use Pusher in Laravel?
Published: 2021-12-29 15:13:32

Install Pusher:
```
composer require pusher/pusher-php-server
```

Register pusher class at `config/app.php`:
```php
'aliases' => [
...
'Pusher' => Pusher\Pusher::class,
...
]
```


Update following values in your `.env` file and if you're using `VaahCMS` update the following details in `.env.<environment-file>` too:

```
BROADCAST_DRIVER=pusher
```

```
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_APP_ID=
PUSHER_APP_CLUSTER=
```

In your `blade` or `view` file add following javascript:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/4.2.1/pusher.min.js"></script>
```

or 

For `Vue` app, install following package:
```sh
npm i pusher-js --save
```

and import:
```js
import Pusher from 'pusher-js';
```

Then send ajax request (javascript/vue) on page load to a controller using following code to authorize pusher instance:
```js

// you need to define following variables to make request
let pusher_key = "";
let pusher_cluster = "";
let pusher_auth_url = "";

let pusher = new Pusher(pusher_key, {
        authEndpoint: pusher_auth_url,
        cluster: pusher_cluster ,
        auth: {
            headers: {
                'X-CSRF-Token': document.querySelector('meta[name=csrf-token]').getAttribute('content')
            }
        }
});
```

In your controller ajax request to authorize the `Pusher`:

```php
public function pusherAuth(Request $request)
{
// Unique channel name 
$channel_name = "presence-<unique-text-OR-id>";  

// Data which you would like to pass to the channel
$data = [ 
        'name' => \Auth::user()->name,
        'id' => \Auth::user()->id,
];

// Initiate Pusher instance
$pusher = new \Pusher( env('PUSHER_KEY'), env('PUSHER_SECRET'), env('PUSHER_APP_ID') );

// This will print auth and channel data
echo $pusher->presenceAuth($channel_name, $request->get('socket_id'), \Auth::user()->id, $data);
}
```

Now, application is authorized to send data to the `$channel_name`.

To send data the pusher channel:

```js
var params = {
channel_name: "<unique-text-OR-id>",  //channel name without "presence" word
channel_data: null
};

// make an ajax request to send this data to a controller's method `pusherSendData`

```

In your controller:

```php
public function pusherSendData(Request $request)
{
    event(new SendDataToPusher($request->all()));
}
```

Create a Laravel Event, eg: `SendDataToPusher.php`:
```php

namespace <NAMESPACE>

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class SendDataToPusher implements ShouldBroadcast
{
    use SerializesModels;

    public $data;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel($this->data['channel_name']);
    }


    public function broadcastWith()
    {
        return $this->data['channel_data'];
    }


    public function broadcastAs()
    {
        $event_name = 'new.data';
        return $event_name;
    }
}

```

The data is sent to the pusher to `$channel_name` with event name `$event_name`.

Now, to receive the data, we need to subcribe to the channel and listen the event. To do that we need to write following js code:
```js
subscribeToPusherChannel: function () {

    let channel_name = "presence-<unique-text-OR-id>";

    channel_subscribed = pusher.subscribe(channel_name); // here the "pusher" is the instance which is created ealier on page load 

    var self = this;

    this.channel.bind('pusher:subscription_succeeded', function(members)
    {
        console.log(channel_name+' channel subscription succeeded');
    });


    //listen to the event new.data
    this.channel.bind("new.data", function(data)
    {
        console.log('New Data Received--->', data);
    });
},
```