I'm creating a chat feature using pusher private channel. When someone from the same thread sends a message, other people in that thread receive the message.
I have created the code as below, but I get error messages:
- Uncaught Options object must provide a cluster
- Uncaught ReferenceError: pusher is not defined
Following are the codes that I have created:
ChatController.php
public function store(Request $request)
{
$thread = Thread::findOrFail($request->thread_id);
Message::create([
'thread_id' => $thread->id,
'user_id' => Auth::id(),
'body' => $request->body,
]);
event(new NewMessage($thread->id, $request->body));
return response()->json([
'status' => 'success',
'message' => 'Your message has been sent successfully.',
]);
}
NewMessage.php
<?php
namespace App\Events;
use App\Models\User;
use Cmgmyr\Messenger\Models\Thread;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $thread_id;
public $message;
public function __construct($thread_id, $message)
{
$this->thread_id = $thread_id;
$this->message = $message;
}
public function broadcastOn(): array
{
return [
new PrivateChannel('chat.' . $this->thread_id)
];
}
}
routes/channels.php
Broadcast::channel('private-chat.{threadId}', function (User $user, Thread $threadId) {
return $threadId->hasParticipant($user->id);
});
resources/js/bootstrap.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
authorizer: (channel) => {
return {
authorize: (socketId, callback) => {
axios.post('/broadcasting/auth', {
socket_id: socketId,
channel_name: channel.name
})
.then(response => {
callback(false, response.data);
})
.catch(error => {
callback(true, error);
});
}
};
},
});
window.Pusher.logToConsole = false;
window.pusher = new window.Pusher(import.meta.env.VITE_PUSHER_APP_KEY, {
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
authEndpoint: `/broadcasting/auth`,
auth: {
headers: {
"Access-Control-Allow-Origin": "*",
}
}
});
resources/js/app.js
import './bootstrap';
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/js/app.js',
],
refresh: true,
}),
],
});
view
@vite('resources/js/app.js')
<script src="https://js.pusher.com/8.2.0/pusher.min.js"></script>
<script type="module">
Pusher.logToConsole = true;
var thread_id = new URL(window.location.href).searchParams.get('id');
var user_id = "{{ auth()->user()->id }}";
var thread = pusher.subscribe('private-chat.' + thread_id);
thread.bind('NewMessage', function(data) {
alert('New message');
});
</script>
How to fix it?
Note: i also use laravel messenger package: https://github.com/cmgmyr/laravel-messenger