diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e14b4..4b745c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Format mengikuti [Keep a Changelog](https://keepachangelog.com/) dan [Semantic Versioning](https://semver.org/). +## [0.5.11] — 2026-11-05 — "gowa-test" + +### Ditambahkan +- Tombol **Test Koneksi** di Admin → WhatsApp → GOWA: menampilkan apakah GOWA terjangkau, status `/health`, kecocokan username/password Basic Auth, dan jumlah device terdaftar. + ## [0.5.10] — 2026-11-05 — "gowa-mode" ### Ditambahkan diff --git a/README.md b/README.md index bba09a6..2c1bba0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@

Lisensi: ISC - Versi 0.5.10 (gowa-mode) + Versi 0.5.11 (gowa-test) Node.js >= 20 Docker Demo diff --git a/package.json b/package.json index 9300688..3fa3055 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-isp", - "version": "0.5.10", + "version": "0.5.11", "description": "OPEN-ISP \u2014 sistem billing & manajemen ISP open-source (PWA pelanggan, multi-OLT, RADIUS, WhatsApp, QRIS)", "main": "app-customer.js", "scripts": { diff --git a/routes/adminPortal.js b/routes/adminPortal.js index 28008d9..bb46c19 100644 --- a/routes/adminPortal.js +++ b/routes/adminPortal.js @@ -6770,6 +6770,16 @@ router.post('/whatsapp/gateway-settings', requireAdminSession, express.urlencode res.redirect('/admin/whatsapp'); }); +router.post('/whatsapp/test-gowa-connection', requireAdminSession, async (req, res) => { + try { + const gowaSvc = require('../services/gowaWhatsappService'); + const r = await gowaSvc.testReachability(); + return res.json(Object.assign({ ok: r.reachable, success: r.reachable }, r)); + } catch (e) { + return res.status(500).json({ ok: false, success: false, message: e.message }); + } +}); + router.post('/whatsapp/test-gowa', requireAdminSession, express.json(), async (req, res) => { try { const { phone, message } = req.body; diff --git a/services/gowaWhatsappService.js b/services/gowaWhatsappService.js index 70b4453..ad8a783 100644 --- a/services/gowaWhatsappService.js +++ b/services/gowaWhatsappService.js @@ -131,6 +131,41 @@ async function sendGowaDocument(toPhone, documentBuffer, filename = 'file.pdf', }); return { success: true, gateway: 'gowa', raw: json }; } +async function testReachability() { + const base = baseUrl(); + const out = { baseUrl: base, reachable: false, healthStatus: 0, authOk: false, devices: 0, message: '' }; + try { + const res = await fetch(base + '/health'); + out.healthStatus = res.status; + out.reachable = res.ok; + } catch (e) { + out.message = 'Tidak terjangkau: ' + e.message; + return out; + } + if (!out.reachable) { + out.message = 'GOWA menjawab, tetapi /health mengembalikan HTTP ' + out.healthStatus; + return out; + } + try { + const res = await fetch(base + '/devices', { headers: commonHeaders() }); + out.authStatus = res.status; + const json = await res.json().catch(function () { return null; }); + const list = (json && Array.isArray(json.results)) ? json.results : []; + if (res.ok) { + out.authOk = true; + out.devices = list.length; + out.message = 'GOWA terjangkau' + (list.length ? ' — ' + list.length + ' device terdaftar' : ' — belum ada device, scan QR untuk menautkan'); + } else if (res.status === 401) { + out.message = 'GOWA terjangkau, tetapi username/password Basic Auth salah atau kosong'; + } else { + out.message = 'GOWA terjangkau, tetapi /devices membalas HTTP ' + res.status; + } + } catch (e) { + out.message = 'GOWA terjangkau, tetapi gagal cek kredensial: ' + e.message; + } + return out; +} + async function testGowaConnection(phone, message) { return await sendGowaMessage(phone, message || 'Tes koneksi GOWA berhasil ✅'); } @@ -225,4 +260,4 @@ async function getLastQrImage() { } } -module.exports = { sendGowaMessage, sendGowaImage, sendGowaDocument, testGowaConnection, gowaStatus, listDevices, ensureDevice, getLoginQr, getLastQrImage, normalizePhoneJid, baseUrl, resolveDeviceId, invalidateDeviceCache }; +module.exports = { sendGowaMessage, sendGowaImage, sendGowaDocument, testGowaConnection, testReachability, gowaStatus, listDevices, ensureDevice, getLoginQr, getLastQrImage, normalizePhoneJid, baseUrl, resolveDeviceId, invalidateDeviceCache }; diff --git a/version.txt b/version.txt index 4e69c2a..cacdf3b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.5.10 \ No newline at end of file +0.5.11 \ No newline at end of file diff --git a/views/admin/whatsapp.ejs b/views/admin/whatsapp.ejs index cf0a477..062af52 100644 --- a/views/admin/whatsapp.ejs +++ b/views/admin/whatsapp.ejs @@ -199,6 +199,8 @@

<%- t('admin.wa.qr_hint','Klik tombol, lalu buka WhatsApp → Perangkat Tertaut → Tautkan perangkat, scan QR. QR berlaku ~30 detik & diperbarui otomatis.') %>
Buka UI GOWA + +