const socket = io({ path: '/proxy/whatsapp/socket.io' }); // UI Elements const statusBadge = document.getElementById('status-badge'); const qrContainer = document.getElementById('qr-container'); const activityLog = document.getElementById('activity-log'); const groupsTableBody = document.getElementById('groups-table-body'); const appsTableBody = document.getElementById('apps-table-body'); const inviteModal = document.getElementById('invite-modal'); const inviteLinkInput = document.getElementById('invite-link-input'); const logoutBtn = document.getElementById('logout-btn'); if (logoutBtn) { logoutBtn.addEventListener('click', async () => { const confirmLogout = confirm('Are you sure you want to log out and change your WhatsApp account? This will disconnect the current session and restart the gateway.'); if (!confirmLogout) return; logoutBtn.disabled = true; logoutBtn.textContent = 'Logging out...'; try { await fetch('api/whatsapp/logout', { method: 'POST' }); alert('Logout initiated! The WhatsApp Gateway is restarting. Please wait 5-10 seconds and then hard-refresh the page to scan a new QR code.'); } catch (err) { console.error('Logout error:', err); alert('Failed to log out cleanly, but restarting anyway. Please refresh.'); } }); } // Tab Switching document.querySelectorAll('.nav-btn').forEach(btn => { btn.addEventListener('click', (e) => { document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active')); document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active')); e.target.classList.add('active'); document.getElementById(e.target.dataset.tab).classList.add('active'); if (e.target.dataset.tab === 'groups') { fetchGroups(); } if (e.target.dataset.tab === 'apps') { fetchApps(); } }); }); // Logging function logActivity(msg, type = 'info') { const entry = document.createElement('p'); entry.className = `log-entry ${type}`; const time = new Date().toLocaleTimeString(); entry.textContent = `[${time}] ${msg}`; activityLog.prepend(entry); } // Socket Events socket.on('status', (data) => { updateStatus(data.ready); if (data.ready) { qrContainer.innerHTML = '

✅ Connected

Session is active and authenticated.

'; } else if (data.qr) { renderQR(data.qr); } }); socket.on('qr', (qr) => { renderQR(qr); logActivity('New QR code generated', 'system'); }); socket.on('ready', () => { updateStatus(true); qrContainer.innerHTML = '

✅ Connected

Session is active and authenticated.

'; logActivity('Client successfully authenticated and ready', 'success'); }); socket.on('disconnected', (reason) => { updateStatus(false); logActivity(`Disconnected: ${reason}`, 'error'); }); socket.on('incoming_message', (msg) => { logActivity(`Msg from ${msg.from}: ${msg.body.substring(0, 50)}...`, 'info'); }); function updateStatus(isReady) { if (isReady) { statusBadge.textContent = 'Connected'; statusBadge.className = 'badge success'; if (logoutBtn) logoutBtn.style.display = 'block'; } else { statusBadge.textContent = 'Disconnected'; statusBadge.className = 'badge error'; if (logoutBtn) logoutBtn.style.display = 'none'; } } function renderQR(qrText) { qrContainer.innerHTML = ''; const qr = qrcode(0, 'L'); qr.addData(qrText); qr.make(); qrContainer.innerHTML = qr.createImgTag(5); } // Groups Tab functionality async function fetchGroups() { groupsTableBody.innerHTML = 'Loading...'; try { const res = await fetch('api/groups'); const data = await res.json(); if (!data.success) { groupsTableBody.innerHTML = `Error: ${data.error || 'Not connected'}`; return; } if (data.groups.length === 0) { groupsTableBody.innerHTML = 'No groups found.'; return; } const settingsRes = await fetch('api/settings'); const settingsData = await settingsRes.json(); const defaultDest = settingsData.settings?.defaultDestination || ''; groupsTableBody.innerHTML = ''; data.groups.forEach(g => { const isDefault = g.id === defaultDest; const tr = document.createElement('tr'); tr.innerHTML = ` ${g.name} ${isDefault ? 'Default' : ''}
${g.id} ${g.participants} ${!isDefault ? `` : ''} `; groupsTableBody.appendChild(tr); }); } catch (e) { groupsTableBody.innerHTML = `Fetch failed.`; } } async function setDefaultDestination(groupId) { try { const res = await fetch('api/settings/default-destination', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ destinationId: groupId }) }); const data = await res.json(); if (data.success) { fetchGroups(); } else { alert('Error setting default: ' + data.error); } } catch (e) { alert('Failed to set default destination.'); } } document.getElementById('add-group-link-form').addEventListener('submit', async (e) => { e.preventDefault(); const btn = e.target.querySelector('button'); const input = document.getElementById('new-invite-link'); btn.disabled = true; btn.textContent = 'Adding...'; try { const res = await fetch('api/groups/add-by-link', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ link: input.value }) }); const data = await res.json(); if (data.success) { input.value = ''; fetchGroups(); } else { alert('Error adding group: ' + data.error); } } catch (err) { alert('Failed to add group'); } btn.disabled = false; btn.textContent = 'Add Group'; }); // Connected Apps functionality async function fetchApps() { appsTableBody.innerHTML = 'Loading...'; try { const res = await fetch('api/apps'); const data = await res.json(); if (!data.success) { appsTableBody.innerHTML = `Error fetching apps`; return; } if (data.apps.length === 0) { appsTableBody.innerHTML = 'No apps connected yet. Send a message to see an app appear here!'; return; } appsTableBody.innerHTML = ''; data.apps.sort((a, b) => new Date(b.lastSeen) - new Date(a.lastSeen)).forEach(app => { const tr = document.createElement('tr'); tr.innerHTML = ` ${app.name} ${app.messageCount} ${new Date(app.lastSeen).toLocaleString()} ${app.lastIp} `; appsTableBody.appendChild(tr); }); } catch (e) { appsTableBody.innerHTML = `Fetch failed.`; } } document.getElementById('btn-refresh-apps').addEventListener('click', fetchApps); document.querySelector('.close-modal').addEventListener('click', () => { inviteModal.classList.remove('active'); }); document.getElementById('btn-copy-link').addEventListener('click', () => { inviteLinkInput.select(); document.execCommand('copy'); alert('Copied to clipboard!'); }); // Test Message document.getElementById('test-msg-form').addEventListener('submit', async (e) => { e.preventDefault(); const btn = e.target.querySelector('button'); const resultDiv = document.getElementById('test-result'); btn.textContent = 'Sending...'; btn.disabled = true; resultDiv.textContent = ''; const to = document.getElementById('test-to').value; const message = document.getElementById('test-body').value; try { const res = await fetch('api/send-message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ to, message }) }); const data = await res.json(); if (data.success) { resultDiv.innerHTML = `✅ Sent successfully (ID: ${data.messageId})`; document.getElementById('test-body').value = ''; } else { resultDiv.innerHTML = `❌ ${data.error}`; } } catch (err) { resultDiv.innerHTML = `❌ Request failed.`; } finally { btn.textContent = 'Send Message'; btn.disabled = false; } });