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 @@
-
+
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 @@