From b98ad7568d7901ab0389b90ec1d08cd71d7069a0 Mon Sep 17 00:00:00 2001 From: oxpoe Date: Thu, 5 Nov 2026 15:55:29 +0700 Subject: [PATCH] fix(gowa): QR sebagai data URI + rewrite qr_link ke base URL publik - gambar tidak lagi bergantung request /qr.png kedua - qr_link host internal diganti origin base URL - log saat gambar gagal diambil; onerror di UI - versi 0.5.9 --- CHANGELOG.md | 7 +++++++ README.md | 2 +- package.json | 2 +- routes/adminPortal.js | 11 ++++++++++- services/gowaWhatsappService.js | 29 ++++++++++++++++++++++++++--- version.txt | 2 +- views/admin/whatsapp.ejs | 2 +- 7 files changed, 47 insertions(+), 8 deletions(-) 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 @@

Lisensi: ISC - Versi 0.5.8 (gowa-qr-error) + Versi 0.5.9 (gowa-qr-image) Node.js >= 20 Docker Demo 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