Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- controller :
- <?php
- namespace App\Http\Controllers\Admin;
- use App\Models\Inbox;
- use App\Models\Device;
- use App\Models\Message;
- use Illuminate\Support\Str;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use App\Http\Controllers\Controller;
- use Exception;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Database\Eloquent\Collection;
- class InboxMessageController extends Controller
- {
- protected $url;
- public function __construct()
- {
- $this->url = config('url.wa_server');
- }
- public function inboxIndexFunction()
- {
- $device = Device::join('inboxes', 'devices.id', '=', 'inboxes.device_id')
- ->select(
- 'devices.name',
- 'devices.number',
- 'devices.expired_date',
- DB::raw('COUNT(inboxes.id) as total_message'),
- 'devices.status',
- 'devices.id'
- )
- ->where('devices.user_id', auth()->user()->id)
- ->where('devices.status', 'AUTHENTICATED')
- ->where('devices.expired_date', '>=', date('Y-m-d'))
- ->groupBy(
- 'devices.id',
- 'devices.name',
- 'devices.number',
- 'devices.expired_date',
- 'devices.status'
- )
- ->get();
- return view('message.inbox.index', compact('device'));
- }
- public function inboxChatFunction($deviceId)
- {
- $inbox = DB::select("
- SELECT i.*
- FROM inboxes i
- WHERE i.device_id = :deviceId
- AND i.id IN (
- SELECT MAX(sub_i.id)
- FROM inboxes sub_i
- WHERE sub_i.device_id = i.device_id
- AND sub_i.remote_jid = i.remote_jid
- GROUP BY sub_i.remote_jid
- )
- ORDER BY i.created_at DESC
- ", ['deviceId' => $deviceId]);
- $device = Device::find($deviceId);
- return view('message.inbox.chat', compact('inbox', 'deviceId', 'device'));
- }
- public function fetchChatMessages($deviceId, $sender)
- {
- // Ambil data perangkat berdasarkan deviceId untuk mendapatkan nomor perangkat (receiver)
- $device = Device::find($deviceId);
- // Periksa apakah perangkat ditemukan
- if (!$device) {
- return response()->json([
- 'error' => 'Device not found'
- ], 404);
- }
- $messages = Inbox::where('device_id', $device->id)
- ->where('remote_jid', $sender)
- ->select('*')
- ->get();
- // Kembalikan pesan dalam format JSON
- return response()->json([
- 'messages' => $messages
- ]);
- }
- public function sendMessage($deviceId, $sender, Request $request)
- {
- $deviceId = $request->device_id;
- $receiver = $request->receiver;
- $message = $request->message;
- $sender = Device::where('id', $deviceId)->value('number');
- $name = Device::where('id', $deviceId)->value('name');
- // random string 10 character sementara
- // $messageId = Str::random(10);
- // kirim message ke whatsapp
- if (!is_array($receiver)) {
- $receiver = [$receiver];
- }
- $send_to_string = $receiver[0] . '@s.whatsapp.net';
- $response = Http::post($this->url . "/send-message", [
- 'sessionId' => $sender,
- 'to' => $send_to_string,
- 'message' => $message
- ]);
- if ($response->failed()) {
- Message::create([
- 'device_id' => $deviceId,
- 'send_to' => $receiver[0],
- 'message' => $message,
- 'status' => 'failed',
- 'is_group' => false,
- 'type' => 'Text Message'
- ]);
- throw new Exception('Request failed with status: ' . $response->status() . ' and message: ' . $response->body());
- } else {
- // save to database
- Message::create([
- 'device_id' => $deviceId,
- 'send_to' => $receiver[0],
- 'message' => $message,
- 'status' => 'sent',
- 'is_group' => false,
- 'type' => 'Text Message'
- ]);
- // Inbox::create([
- // 'device_id' => $deviceId,
- // 'sender' => $sender,
- // 'receiver' => $receiver[0],
- // 'message' => $message,
- // 'subject' => 'sender',
- // 'status' => 'sent',
- // 'name' => $name,
- // 'message_id' => $messageId
- // ]);
- return response()->json([
- 'success' => true,
- 'message' => 'Message sent successfully'
- ]);
- }
- }
- public function checkDeviceFunction($deviceId)
- {
- $device = Device::where('number', $deviceId)->value('id');
- return response()->json([
- 'device' => $device
- ]);
- }
- }
- blade :
- @extends('partials.master')
- @section('title', 'Message')
- @push('custom_styles')
- <style>
- .chat-message {
- height: 500px;
- background-image: url("{{asset('admin/assets/images/message/background_whatsapp.jpeg')}}");
- background-size: cover;
- overflow-y: auto;
- }
- .card-custom:hover .card-title {
- color: #fff !important;
- }
- .card-custom .card-title {
- color: #2755CE !important;
- }
- .chat-item {
- background-color: #F2F4F7;
- border-color: #2755CE;
- border-radius: 6px;
- display: flex;
- align-items: center;
- }
- .chat-item img {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- }
- .chat-item-selected {
- background-color: #6581ca;
- color: #fff;
- border-color: #6581ca;
- border-radius: 6px;
- display: flex;
- align-items: center;
- }
- .chat-item-selected img {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- }
- .app-content {
- overflow: hidden;
- height: 100vh;
- /* Pastikan tinggi utama diatur ke layar penuh */
- }
- /* Aktifkan scroll pada "Chat Room" */
- .mailbox-list {
- overflow-y: auto;
- max-height: calc(100vh - 200px);
- scrollbar-width: none;
- -ms-overflow-style: none;
- }
- /* Aktifkan scroll pada "Chat Messages" hanya saat mouse berada di atas */
- .chat-message {
- height: 400px;
- /* Tinggi tetap untuk kontainer pesan */
- overflow-y: hidden;
- /* Default tidak ada scroll */
- }
- /* Aktifkan scroll saat mouse berada di atas "Chat Messages" */
- .chat-message:hover {
- overflow-y: auto;
- /* Scroll aktif saat hover */
- }
- .message-text {
- white-space: pre-wrap;
- }
- </style>
- @endpush
- @section('content')
- <div class="app-content">
- <div class="content-wrapper">
- <div class="container-fluid">
- <div class="row">
- <div class="col">
- {{-- Basic Card --}}
- <div class="card" id="chat-card">
- <div class="card-header">
- <h5 class="card-title">Inbox Message</h5>
- </div>
- <div class="card-body">
- <div class="col-md-12">
- <div class="row">
- {{-- Chat Room --}}
- <div class="col-md-4 my-3">
- <h5 class="mb-3">Chat Room</h5>
- <input type="text" class="form-control" placeholder="Search chat" oninput="handleSearchContact(event)">
- {{-- List Chat --}}
- <div class="mailbox-list">
- @foreach ($inbox as $item)
- <div class="chat-item my-3 p-2" data-chat-id="{{ $item->device_id }}"
- data-remote_jid="{{ $item->remote_jid }}" data-receiver="{{ $item->receiver }}"
- data-name="{{ $item->name }}" data-message="{{ $item->message }}"
- id="list-chat" style="cursor: pointer;">
- <div class="mailbox-list-item-content my-auto me-auto">
- <span class="mailbox-list-item-title fw-bold">
- {{ $item->name }}
- </span>
- <p class="mailbox-list-item-text fw-lighter">
- {{ Str::limit($item->message, 10) }}
- </p>
- </div>
- <div class="ms-auto me-3">
- <span class="badge badge-secondary">
- @php
- $createdAt = \Carbon\Carbon::parse($item->created_at);
- $now = \Carbon\Carbon::now();
- $diffInSeconds = $createdAt->diffInSeconds($now);
- $diffInMinutes = $createdAt->diffInMinutes($now);
- $diffInHours = $createdAt->diffInHours($now);
- if ($diffInHours < 24) {
- if ($diffInMinutes < 1) {
- echo $diffInSeconds . ' second' . ($diffInSeconds> 1 ? 's' : '') . ' ago';
- } elseif ($diffInHours < 1) {
- echo $diffInMinutes . ' minute' . ($diffInMinutes> 1 ? 's' : '') . ' ago';
- } else {
- echo $diffInHours . ' hour' . ($diffInHours > 1 ? 's' : '') . ' ago';
- }
- } else {
- echo $createdAt->format('d M Y H:i');
- }
- @endphp
- </span>
- </div>
- </div>
- @endforeach
- </div>
- </div>
- <div class="col-md-8" id="chat-area">
- <div class="card">
- <div class="card-header">
- <h5 class="card-title">Select a chat to view messages</h5>
- </div>
- <div class="card-body chat-message"
- style="
- height: calc(100vh - 250px);
- overflow-y: auto; display: flex; flex-direction: column;"
- >
- <p class="text-muted">No chat selected.</p>
- </div>
- <div class="card-footer">
- <div class="d-flex justify-content-between">
- <textarea class="form-control" placeholder="Type your message"
- disabled></textarea>
- <button class="btn btn-primary my-3 ms-3" disabled>Send</button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- @endsection
- @push('custom_script')
- <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/dayjs.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/plugin/relativeTime.min.js"></script>
- <script>
- const API_URL = "{{config('url.wa_server')}}"; // URL backend
- const WS_URL = "{{config('url.websocket_server')}}"; // URL WebSocket backend
- const connectedSessions = new Set();
- let ws;
- let remote_jid_selected;
- let inboxData = @json($inbox);
- let messages = [];
- dayjs.extend(dayjs_plugin_relativeTime);
- console.log('');
- function handleSearchContact(e) {
- const inputValue = e.target.value;
- console.log(inputValue);
- const result = findByNameLike(inboxData, inputValue);
- renderMailbox(result)
- }
- function findByNameLike(inboxData, keyword) {
- return inboxData.filter(item => item.name.toLowerCase().includes(keyword.toLowerCase()));
- }
- if (ws) {
- ws.close();
- }
- // Buat koneksi WebSocket baru
- ws = new WebSocket(WS_URL);
- ws.onopen = () => {
- console.log(`WebSocket connected `);
- };
- ws.onclose = () => {
- console.log(`WebSocket disconnected `);
- };
- function formatTimestamp(timestamp) {
- const date = new Date(timestamp);
- return date.toLocaleString(); // You can customize the format as needed
- }
- ws.onmessage = (event) => {
- const data = JSON.parse(event.data);
- if (data.sessionId == '{{$device->number}}') {
- if (data.type == "notify") {
- if (data.messageType == "REVOKE") {
- const inboxIndex = inboxData.findIndex(
- (msg) => msg.remote_jid === data.remote_jid
- );
- if (inboxIndex !== -1) {
- if (data.latestMessage) {
- inboxData[inboxIndex] = {
- ...inboxData[inboxIndex],
- ...data.latestMessage
- };
- } else {
- inboxData.splice(inboxIndex, 1);
- }
- }
- const filteredInboxData = messages[data.remote_jid]?.filter(inbox => {
- if (inbox.message_id !== data.id) {
- return inbox.message_id
- }
- });
- messages[data.remote_jid] = filteredInboxData
- renderChat()
- renderMailbox(inboxData)
- } else {
- const chatMessageDiv = $('#chat-area .chat-message');
- let replace = 0;
- inboxData.forEach((inbox, index) => {
- if (inbox.remote_jid === data.message.remote_jid) {
- inboxData[index] = data.message;
- replace += 1;
- }
- });
- if (replace === 0) {
- inboxData.push(data.message);
- }
- renderMailbox(inboxData)
- if (remote_jid_selected == data.message.remote_jid) {
- messages[remote_jid_selected].push(data.message)
- messages[remote_jid_selected].sort(
- (a, b) => new Date(a.created_at) - new Date(b.created_at)
- );
- renderChat();
- }
- }
- console.log("contact", inboxData);
- }
- }
- };
- function renderMailbox(inboxData) {
- inboxData.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
- $('.mailbox-list').empty();
- inboxData.forEach(element => {
- const newChatItem = `
- <div class="chat-item my-3 p-2" data-chat-id="${element.deviceId}"
- data-remote_jid="${element.remote_jid}" data-receiver="${element.receiver}"
- data-name="${element.name}" data-message="${element.message}"
- style="cursor: pointer;">
- <div class="mailbox-list-item-content my-auto me-auto">
- <span class="mailbox-list-item-title fw-bold">${element.name}</span>
- <p class="mailbox-list-item-text fw-lighter">
- ${element.message.length > 10 ? element.message.substring(0, 10) + '...' : element.message}
- </p>
- </div>
- <div class="ms-auto me-3">
- <span class="badge badge-secondary">${dayjs(element.created_at).fromNow()}</span>
- </div>
- </div>
- `;
- $('.mailbox-list').append(newChatItem); // Menambahkan item baru ke dalam .mailbox-list
- });
- }
- function renderChat() {
- const chatMessageDiv = $('#chat-area .chat-message');
- chatMessageDiv.empty();
- if (messages[remote_jid_selected]?.length > 0) {
- // Iterate through each message and append to the chat area
- messages[remote_jid_selected].forEach(function(message) {
- console.log(message);
- const isSender = message.from_me == 0 ? true : false;
- const message_text = message.message ? message.message : "<b>Maaf chat ini tidak dapat kami tampilkan</b>"
- const messageElement = `
- <div class="message-item mb-3 d-flex ${isSender ? 'justify-content-start' : 'justify-content-end'}">
- <div class="message-content p-2 rounded ${isSender ? 'bg-light text-dark' : 'bg-primary text-white'}" style="max-width: 70%;">
- <p class="mb-1 message-text">${message_text}</p>
- <small style="${isSender ? 'text-end' : 'text-start'}">${formatTimestamp(message.created_at)}</small>
- </div>
- </div>
- `;
- chatMessageDiv.append(messageElement);
- });
- // Scroll to the bottom of the chat messages
- chatMessageDiv.scrollTop(chatMessageDiv[0].scrollHeight);
- } else {
- // If no messages, display a placeholder
- chatMessageDiv.append(
- '<p class="text-muted">No messages in this chat.</p>');
- }
- // Enable the textarea and send button
- $('#chat-area textarea').prop('disabled', false);
- $('#chat-area button').prop('disabled', false);
- }
- $(document).ready(function() {
- // Function to format the timestamp to a readable format
- function formatTimestamp(timestamp) {
- const date = new Date(timestamp);
- return date.toLocaleString(); // You can customize the format as needed
- }
- // Event listener for chat item clicks
- $('.mailbox-list').on('click', '.chat-item', function() {
- // Retrieve data attributes from the clicked chat item
- const deviceId = $(this).data('chat-id');
- const remote_jid = $(this).data('remote_jid');
- const receiver = $(this).data('receiver');
- const name = $(this).data('name');
- remote_jid_selected = remote_jid;
- // Optional: Highlight the selected chat item
- $('.chat-item').removeClass('active'); // Remove active class from all
- $(this).addClass('active'); // Add active class to the clicked one
- // Update the chat area header with the selected chat's name
- $('#chat-area .card-header .card-title').text(`Chat with ${name}`);
- // Make an AJAX GET request to fetch chat messages
- $.ajax({
- url: `/admin/message/inbox/fetch-chat/{{$deviceId}}/${remote_jid_selected}`,
- method: 'GET',
- dataType: 'json',
- success: function(response) {
- // Clear the current chat messages
- messages = [];
- messages[remote_jid] = response.messages;
- renderChat();
- },
- error: function(xhr, status, error) {
- console.error('Error fetching chat messages:', error);
- alert('Failed to load chat messages. Please try again.');
- }
- });
- });
- // Optional: Handle sending messages
- $('#chat-area button').on('click', function() {
- const message = $('#chat-area textarea').val().trim();
- if (message === '') {
- alert('Please enter a message.');
- return;
- }
- // Disable the send button to prevent multiple clicks
- $(this).prop('disabled', true);
- console.log("{{$deviceId}}", remote_jid_selected);
- // Make an AJAX POST request to send the message
- $.ajax({
- url: `/admin/message/inbox/send-message/{{$deviceId}}/${remote_jid_selected}`, // Ensure this route exists in your routes file
- method: 'POST',
- dataType: 'json',
- data: {
- device_id: "{{$deviceId}}",
- receiver: remote_jid_selected,
- message: message,
- _token: '{{ csrf_token() }}' // Include CSRF token
- },
- success: function(response) {
- // Clear the textarea
- $('#chat-area textarea').val('');
- // Optionally, append the new message to the chat area
- const chatMessageDiv = $('#chat-area .chat-message');
- const messageElement = `
- <div class="message-item mb-3 d-flex justify-content-end">
- <div class="message-content p-2 rounded bg-primary text-white" style="max-width: 50%;">
- <p class="mb-1">${message}</p>
- <small style="text-end">${formatTimestamp(new Date())}</small>
- </div>
- </div>
- `;
- // chatMessageDiv.append(messageElement);
- chatMessageDiv.scrollTop(chatMessageDiv[0].scrollHeight);
- // Re-enable the send button
- $('#chat-area button').prop('disabled', false);
- },
- error: function(xhr, status, error) {
- console.error('Error sending message:', error);
- alert('Failed to send message. Please try again.');
- $('#chat-area button').prop('disabled', false);
- }
- });
- });
- });
- </script>
- @endpush
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement