fix(gowa): status device array, auto-save device id, QR hide saat terhubung
All checks were successful
CI / test (push) Successful in 1m53s
All checks were successful
CI / test (push) Successful in 1m53s
- status route normalisasi results array + auto isi gowa_device_id - UI poll status 3s, sembunyikan QR saat open - resolveDeviceId utamakan device connected - versi 0.5.17
This commit is contained in:
@@ -2,6 +2,14 @@
|
||||
|
||||
Format mengikuti [Keep a Changelog](https://keepachangelog.com/) dan [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [0.5.17] — 2026-11-06 — "gowa-connected"
|
||||
|
||||
### Diperbaiki
|
||||
- Status GOWA membaca array `/devices` (banyak device) sehingga tidak lagi selalu menampilkan **Belum Terhubung** ketika Device ID belum diisi.
|
||||
- Device yang terhubung disimpan otomatis sebagai `gowa_device_id` — tidak perlu menyalin ID manual dari UI GOWA.
|
||||
- Setelah scan QR, halaman memantau status tiap 3 detik; QR otomatis disembunyikan dan status berubah **Terhubung** saat berhasil.
|
||||
- Pengiriman memilih device yang benar-benar terhubung bila ada lebih dari satu device.
|
||||
|
||||
## [0.5.16] — 2026-11-05 — "restart-help"
|
||||
|
||||
### Ditambahkan
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/lisensi-ISC-ADFF2F" alt="Lisensi: ISC">
|
||||
<img src="https://img.shields.io/badge/versi-0.5.16_restart--help-ADFF2F" alt="Versi 0.5.16 (restart-help)">
|
||||
<img src="https://img.shields.io/badge/versi-0.5.17_gowa--connected-ADFF2F" alt="Versi 0.5.17 (gowa-connected)">
|
||||
<img src="https://img.shields.io/badge/Node.js-%E2%89%A520-339933" alt="Node.js >= 20">
|
||||
<img src="https://img.shields.io/badge/docker-ready-2496ED?logo=docker&logoColor=white" alt="Docker">
|
||||
<a href="https://demo-openisp.oxpoe.xyz"><img src="https://img.shields.io/badge/demo-live-ADFF2F?logo=googlechrome&logoColor=black" alt="Demo"></a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "open-isp",
|
||||
"version": "0.5.16",
|
||||
"version": "0.5.17",
|
||||
"description": "OPEN-ISP \u2014 sistem billing & manajemen ISP open-source (PWA pelanggan, multi-OLT, RADIUS, WhatsApp, QRIS)",
|
||||
"main": "app-customer.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -7388,11 +7388,27 @@ router.get('/api/whatsapp/status', requireAdmin, async (req, res) => {
|
||||
} else if (gatewayType === 'gowa') {
|
||||
let st = null;
|
||||
try { st = await require('../services/gowaWhatsappService').gowaStatus(); } catch (e) { st = { ok: false, error: e.message }; }
|
||||
const rr = (st && st.data && st.data.results) || {};
|
||||
const loggedIn = !!(rr.is_logged_in || rr.isConnected || rr.connected);
|
||||
const isConn = !!(rr.is_connected || rr.connected);
|
||||
// /devices mengembalikan array (banyak device); /devices/:id/status mengembalikan objek.
|
||||
const raw = st && st.data && st.data.results;
|
||||
const list = Array.isArray(raw) ? raw : ((raw && typeof raw === 'object') ? [raw] : []);
|
||||
const pick = list.find(function (d) {
|
||||
return d && (d.is_connected || d.is_logged_in || d.connected ||
|
||||
d.state === 'connected' || d.state === 'logged_in');
|
||||
}) || list[0] || {};
|
||||
const loggedIn = !!(pick.is_logged_in || pick.is_connected || pick.connected ||
|
||||
pick.state === 'connected' || pick.state === 'logged_in');
|
||||
const isConn = !!(pick.is_connected || pick.connected || pick.state === 'connected');
|
||||
const conn = isConn ? 'open' : (loggedIn ? 'connecting' : 'close');
|
||||
res.json({ connection: conn, gateway: 'gowa', loggedIn: loggedIn, user: { id: 'gowa_gateway', name: loggedIn ? 'GOWA (WhatsApp)' : 'GOWA Gateway' }, lastUpdate: new Date().toISOString() });
|
||||
const deviceId = String(pick.device_id || pick.id || '').trim();
|
||||
// Simpan otomatis device id agar status berikutnya memakai /devices/:id/status.
|
||||
if (deviceId && !String(getSetting('gowa_device_id', '') || '').trim()) {
|
||||
try { saveSettings({ gowa_device_id: deviceId }); } catch (e) {}
|
||||
}
|
||||
res.json({
|
||||
connection: conn, gateway: 'gowa', loggedIn: loggedIn, deviceId: deviceId,
|
||||
user: { id: deviceId || 'gowa_gateway', name: loggedIn ? 'GOWA (WhatsApp)' : 'GOWA Gateway' },
|
||||
lastUpdate: new Date().toISOString()
|
||||
});
|
||||
} else if (gatewayType === 'baileys') {
|
||||
const { whatsappStatus, startWhatsAppBot, isBotRunning } = await import('../services/whatsappBot.mjs');
|
||||
if (getSetting('whatsapp_enabled', true) && !isBotRunning() && whatsappStatus.connection !== 'open' && whatsappStatus.connection !== 'qr') {
|
||||
|
||||
@@ -44,7 +44,11 @@ async function resolveDeviceId(force) {
|
||||
try { list = await listDevices(); } catch (e) { list = []; }
|
||||
const has = function (id) { return list.some(function (d) { return String(d.id) === id; }); };
|
||||
let chosen;
|
||||
const connected = list.find(function (d) {
|
||||
return d && (d.state === 'connected' || d.is_connected || d.is_logged_in || d.connected);
|
||||
});
|
||||
if (configured && has(configured)) chosen = configured; // device id diset & ada -> pakai itu
|
||||
else if (connected) chosen = String(connected.id); // utamakan device yang benar-benar terhubung
|
||||
else if (list.length === 1) chosen = String(list[0].id); // cuma 1 device -> otomatis
|
||||
else if (list.length > 1) chosen = configured || String(list[0].id); // >1 device -> pakai yg diset / pertama
|
||||
else chosen = configured; // GOWA tak beri list -> serahkan ke GOWA
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.5.16
|
||||
0.5.17
|
||||
@@ -290,12 +290,38 @@
|
||||
// Cooldown QR disinkronkan dengan GoWA: interval mengikuti qr_duration dari server.
|
||||
var _gowaQrRefresh = null; // penjadwal ambil QR berikutnya (timeout)
|
||||
var _gowaQrTick = null; // interval hitung mundur 1 detik
|
||||
var _gowaQrPoll = null; // pantau status setelah scan
|
||||
function showGowaQr() {
|
||||
var wrap = document.getElementById('gowa_qr_wrap');
|
||||
if (wrap) wrap.style.display = 'block';
|
||||
var st = document.getElementById('gowa_qr_status');
|
||||
if (st) st.textContent = 'Memuat QR...';
|
||||
if (st) { st.style.color = 'var(--muted)'; st.textContent = 'Memuat QR...'; }
|
||||
gowaQrCycle();
|
||||
startGowaPoll();
|
||||
}
|
||||
function stopGowaPoll() {
|
||||
if (_gowaQrPoll) { clearInterval(_gowaQrPoll); _gowaQrPoll = null; }
|
||||
}
|
||||
function startGowaPoll() {
|
||||
stopGowaPoll();
|
||||
_gowaQrPoll = setInterval(async function () {
|
||||
try {
|
||||
var r = await fetch('/admin/api/whatsapp/status', { cache: 'no-store' });
|
||||
var s = await r.json();
|
||||
var st = document.getElementById('gowa_qr_status');
|
||||
if (s && s.connection === 'open') {
|
||||
if (_gowaQrRefresh) { clearTimeout(_gowaQrRefresh); _gowaQrRefresh = null; }
|
||||
if (_gowaQrTick) { clearInterval(_gowaQrTick); _gowaQrTick = null; }
|
||||
stopGowaPoll();
|
||||
var img = document.getElementById('gowa_qr_img'); if (img) img.src = '';
|
||||
var wrap = document.getElementById('gowa_qr_wrap'); if (wrap) wrap.style.display = 'none';
|
||||
if (st) { st.style.color = 'var(--success)'; st.textContent = '✅ Terhubung ke WhatsApp.'; }
|
||||
if (typeof checkStatus === 'function') checkStatus();
|
||||
} else if (s && s.connection === 'connecting') {
|
||||
if (st) { st.style.color = 'var(--warning, #f59e0b)'; st.textContent = 'Terautentikasi, sedang menyinkronkan...'; }
|
||||
}
|
||||
} catch (e) {}
|
||||
}, 3000);
|
||||
}
|
||||
function gowaQrCycle() {
|
||||
fetch('/admin/whatsapp/gowa/qr', { cache: 'no-store' }).then(function (r) { return r.json(); }).then(function (d) {
|
||||
|
||||
Reference in New Issue
Block a user