diff --git a/CHANGELOG.md b/CHANGELOG.md index f00482f..37657a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ Format mengikuti [Keep a Changelog](https://keepachangelog.com/) dan [Semantic Versioning](https://semver.org/). +## [0.5.9] — 2026-11-05 — "gowa-qr-image" + +### Diperbaiki +- QR GOWA dikirim sebagai **data URI** sehingga gambar tetap tampil walau app berjalan multi-proses atau request gambar terpisah gagal. +- `qr_link` dari GOWA yang menunjuk host internal (`127.0.0.1`/container) ditulis ulang memakai base URL publik yang dikonfigurasi. +- Log peringatan `[GOWA] Gagal ambil gambar QR` bila pengambilan gambar gagal. + ## [0.5.8] — 2026-11-05 — "gowa-qr-error" ### Diperbaiki diff --git a/README.md b/README.md index f515538..9a96377 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@
-
+
diff --git a/package.json b/package.json
index da3a9ab..62001a3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "open-isp",
- "version": "0.5.8",
+ "version": "0.5.9",
"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 182e567..a46e83d 100644
--- a/routes/adminPortal.js
+++ b/routes/adminPortal.js
@@ -6654,7 +6654,16 @@ router.get('/whatsapp/gowa/qr', requireAdminSession, async (req, res) => {
const detail = r.message || r.code || 'pastikan GOWA berjalan & username/password Basic Auth benar';
return res.json({ ok: false, status: r.status || 0, message: 'Gagal membuat QR: ' + (r.status ? 'HTTP ' + r.status + ' — ' : '') + detail + '.' });
}
- return res.json({ ok: true, image: '/admin/whatsapp/gowa/qr.png?v=' + Date.now(), device_id: r.device_id, duration: r.duration });
+ // Kirim gambar langsung sebagai data URI: tidak bergantung pada request
+ // kedua /qr.png (aman bila app berjalan multi-proses) dan tidak kena cache.
+ let image = '/admin/whatsapp/gowa/qr.png?v=' + Date.now();
+ try {
+ const img = await gowa.getLastQrImage();
+ if (img && img.buffer && img.buffer.length) {
+ image = 'data:' + (img.contentType || 'image/png') + ';base64,' + img.buffer.toString('base64');
+ }
+ } catch (e) {}
+ return res.json({ ok: true, image, device_id: r.device_id, duration: r.duration });
} catch (e) { return res.json({ ok: false, message: e.message }); }
});
diff --git a/services/gowaWhatsappService.js b/services/gowaWhatsappService.js
index 78a2925..70b4453 100644
--- a/services/gowaWhatsappService.js
+++ b/services/gowaWhatsappService.js
@@ -192,14 +192,37 @@ async function getLoginQr(deviceId) {
return { ok: false, status: 0, code: null, message: e.message };
}
}
+// GOWA bisa mengembalikan qr_link absolut ke host internal (127.0.0.1 / nama
+// container). Ambil path-nya saja lalu tempel ke base URL yang dikonfigurasi,
+// supaya gambar tetap bisa diambil saat GOWA diakses lewat domain/reverse proxy.
+function resolveQrLink(link) {
+ const l = String(link || '').trim();
+ if (!l) return '';
+ if (/^data:/i.test(l)) return l;
+ try {
+ const u = new URL(l, baseUrl() + '/');
+ const base = new URL(baseUrl());
+ return base.origin + u.pathname + u.search;
+ } catch (e) {
+ return baseUrl() + (l.charAt(0) === '/' ? l : '/' + l);
+ }
+}
+
async function getLastQrImage() {
if (!_lastQr.link) return null;
+ const url = resolveQrLink(_lastQr.link);
try {
- const res = await fetch(_lastQr.link, { headers: commonHeaders() });
- if (!res.ok) return null;
+ const res = await fetch(url, { headers: commonHeaders() });
+ if (!res.ok) {
+ logger.warn(`[GOWA] Gagal ambil gambar QR: HTTP ${res.status} (${url})`);
+ return null;
+ }
const buf = Buffer.from(await res.arrayBuffer());
return { buffer: buf, contentType: res.headers.get('content-type') || 'image/png' };
- } catch (e) { return null; }
+ } catch (e) {
+ logger.warn(`[GOWA] Gagal ambil gambar QR: ${e.message} (${url})`);
+ return null;
+ }
}
module.exports = { sendGowaMessage, sendGowaImage, sendGowaDocument, testGowaConnection, gowaStatus, listDevices, ensureDevice, getLoginQr, getLastQrImage, normalizePhoneJid, baseUrl, resolveDeviceId, invalidateDeviceCache };
diff --git a/version.txt b/version.txt
index b35b9dd..89235c0 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-0.5.8
\ No newline at end of file
+0.5.9
\ No newline at end of file
diff --git a/views/admin/whatsapp.ejs b/views/admin/whatsapp.ejs
index 8cefba4..ac0b93d 100644
--- a/views/admin/whatsapp.ejs
+++ b/views/admin/whatsapp.ejs
@@ -181,7 +181,7 @@
Buka UI GOWA