NotifMoo JavaScript Client
Dokumentasi cara menggunakan NotifMoo via CDN untuk menerima notifikasi real‑time dari Notif.
← Kembali ke Dashboard1. Menambahkan CDN
Tambahkan skrip berikut di bagian <head> atau sebelum </body> pada
aplikasi Anda.
Ganti YOUR_API_KEY dengan API key domain yang Anda buat di Dashboard.
Anda juga bisa menambahkan parameter opsional host bila ingin mengarah ke endpoint WebSocket
lain:
Catatan: Origin (domain) halaman Anda harus sama dengan domain yang terdaftar di Dashboard agar API key valid.
2. Objek Global NotifMoo
Setelah skrip CDN dimuat, library akan otomatis mencoba konek ke WebSocket dan menambahkan objek global
NotifMoo.
NotifMoo.connect(): memulai koneksi (biasanya otomatis dipanggil).NotifMoo.subscribe(channel, options): subscribe ke channel tertentu.NotifMoo.unsubscribe(channel): unsubscribe dari channel.NotifMoo.bind(event, callback): listen event global tertentu.NotifMoo.onConnect(callback): dipanggil ketika koneksi berhasil.NotifMoo.onError(callback): menangkap error koneksi.
Library ini mirip dengan client Pusher: setiap pesan memiliki event, channel, dan
data.
3. Contoh Sederhana
Contoh halaman HTML lengkap yang subscribe ke channel publik dan menampilkan pesan yang diterima.
<html lang="en">
<head>
<meta charset="UTF-8">
<title>NotifMoo Demo</title>
<script src="https://cdn.jsdelivr.net/gh/pimphand/notifmoo_@main/setup.js?apikey=YOUR_API_KEY"></script>
</head>
<body>
<h1>NotifMoo Demo</h1>
<pre id="log"></pre>
<script>
function log(line) {
document.getElementById('log').textContent += line + '\n';
}
NotifMoo.onConnect(function () {
log('Connected! socket_id=' + NotifMoo.socketId);
// Subscribe ke channel, misalnya "public-demo"
NotifMoo.subscribe('public-demo', {
onMessage: function (msg) {
log('[channel=' + msg.channel + '] event=' + msg.event + ' data=' + JSON.stringify(msg.data));
}
});
});
NotifMoo.onError(function (err) {
log('ERROR: ' + err.message + (err.code ? ' (code=' + err.code + ')' : ''));
});
</script>
</body>
</html>
4. Contoh dengan Channel Per‑User
Misalkan backend Anda mengirim notifikasi ke channel seperti user.123 (123 = ID user).
Berikut contoh cara subscribe dari frontend:
const userId = 123;
const channelName = `user.${userId}`;
NotifMoo.onConnect(function () {
NotifMoo.subscribe(channelName, {
onMessage: function (msg) {
console.log('New notification for user', msg);
}
});
});
5. Event Global
Selain onMessage per‑channel, Anda bisa menangkap semua event yang masuk dengan event global:
NotifMoo.bind('*', function (payload) {
console.log('EVENT', payload.event, 'CHANNEL', payload.channel, 'DATA', payload.data);
});
// Event khusus, misalnya "order.updated"
NotifMoo.bind('order.updated', function (payload) {
console.log('Order updated:', payload.data);
});
6. Contoh Aplikasi Chat Sederhana
Contoh berikut adalah versi sederhana dari file demo chat-demo.html: tampilan bubble mirip
WhatsApp,
subscribe ke satu channel, dan mengirim pesan menggunakan HTTP API POST /api/broadcast.
<html lang="en">
<head>
<meta charset="UTF-8">
<title>NotifMoo Chat Demo</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; padding: 16px; background: #f1f5f9; }
.card { max-width: 480px; margin: 0 auto; background: #fff; border-radius: 12px; box-shadow: 0 10px 15px -3px rgba(15,23,42,0.1), 0 4px 6px -4px rgba(15,23,42,0.1); padding: 16px; }
#messages { border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px; height: 260px; overflow-y: auto; background: #f8fafc; font-size: 14px; display: flex; flex-direction: column; gap: 4px; }
.msg-row { display: flex; margin-bottom: 4px; }
.msg-row.msg-other { justify-content: flex-start; }
.msg-row.msg-me { justify-content: flex-end; }
.msg-bubble { max-width: 80%; border-radius: 12px; padding: 6px 8px; box-shadow: 0 1px 1px rgba(15,23,42,0.08); word-wrap: break-word; }
.msg-row.msg-other .msg-bubble { background: #ffffff; }
.msg-row.msg-me .msg-bubble { background: #dcfce7; }
.msg-name { font-size: 10px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; color: #64748b; margin-bottom: 2px; }
.msg-text { font-size: 13px; color: #0f172a; }
.inputs { display: flex; gap: 6px; margin-top: 8px; }
.inputs input { border-radius: 6px; border: 1px solid #cbd5f5; padding: 6px 8px; font-size: 13px; }
.inputs input[name="name"] { width: 110px; }
.inputs input[name="text"] { flex: 1; }
button { border-radius: 6px; border: none; background: #4f46e5; color: #fff; padding: 6px 10px; font-size: 13px; cursor: pointer; white-space: nowrap; }
</style>
<!-- Ganti YOUR_API_KEY dengan API key domain Anda -->
<script src="https://cdn.jsdelivr.net/gh/pimphand/notifmoo_@main/setup.js?apikey=YOUR_API_KEY"></script>
</head>
<body>
<div class="card">
<h1>NotifMoo Chat Demo</h1>
<div class="meta" id="meta" style="font-size:11px;color:#94a3b8;margin-bottom:6px;"></div>
<div id="messages"></div>
<div class="inputs">
<input id="name" name="name" placeholder="Nama Anda" />
<input id="text" name="text" placeholder="Tulis pesan..." />
<button id="send">Kirim</button>
</div>
</div>
<script>
function getQueryParam(key, fallback) {
const params = new URLSearchParams(window.location.search);
return params.get(key) || fallback;
}
const room = getQueryParam('room', 'chat.room1');
const defaultName = getQueryParam('name', 'Client');
const nameInput = document.getElementById('name');
const textInput = document.getElementById('text');
const sendBtn = document.getElementById('send');
const metaEl = document.getElementById('meta');
const messagesEl = document.getElementById('messages');
nameInput.value = defaultName;
metaEl.textContent = 'Channel: ' + room + ' — socket: connecting...';
const recentKeys = [];
function isDuplicateMessage(payload) {
try {
const key = JSON.stringify(payload || {});
if (recentKeys.indexOf(key) !== -1) return true;
recentKeys.push(key);
if (recentKeys.length > 50) recentKeys.shift();
return false;
} catch (e) {
return false;
}
}
function addMessage(payload) {
if (isDuplicateMessage(payload)) return;
const data = (payload && payload.data) || {};
const name = data.name || 'anon';
const text = data.text || '';
const row = document.createElement('div');
const isMe = (nameInput.value || defaultName) === name;
row.className = 'msg-row ' + (isMe ? 'msg-me' : 'msg-other');
const bubble = document.createElement('div');
bubble.className = 'msg-bubble';
const nameEl = document.createElement('div');
nameEl.className = 'msg-name';
nameEl.textContent = name.toUpperCase();
const textEl = document.createElement('div');
textEl.className = 'msg-text';
textEl.textContent = text;
bubble.appendChild(nameEl);
bubble.appendChild(textEl);
row.appendChild(bubble);
messagesEl.appendChild(row);
messagesEl.scrollTop = messagesEl.scrollHeight;
}
NotifMoo.onConnect(function () {
metaEl.textContent = 'Channel: ' + room + ' — connected, menunggu socket_id...';
NotifMoo.subscribe(room, {
onMessage: function (msg) { addMessage(msg); }
});
});
NotifMoo.bind('connection_established', function (payload) {
if (!payload || !payload.socket_id) return;
metaEl.textContent = 'Channel: ' + room + ' — socket_id: ' + payload.socket_id;
});
NotifMoo.onError(function (err) {
metaEl.textContent = 'ERROR: ' + err.message + (err.code ? ' (code=' + err.code + ')' : '');
});
sendBtn.addEventListener('click', function () {
const name = nameInput.value || 'anon';
const text = textInput.value;
if (!text) return;
textInput.value = '';
// Kirim pesan via HTTP API resmi Notif (POST /api/broadcast)
fetch('https://notifmoo.dmpt.my.id/api/broadcast', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-app-key': 'YOUR_APP_KEY'
},
body: JSON.stringify({
channel: room,
event: 'chat.message',
data: { name, text }
})
}).catch(function (e) {
console.error('Gagal kirim pesan', e);
});
});
</script>
</body>
</html>
Ganti YOUR_API_KEY dan YOUR_APP_KEY dengan kredensial dari Dashboard. Untuk demo
penuh yang
bisa membuka dua jendela sekaligus dengan channel acak, gunakan tombol di bagian berikutnya (Demo Cepat).
7. Demo Cepat: Buka 2 Jendela Chat
Untuk mencoba dua client chat sekaligus, klik tombol di bawah ini. Halaman akan membuka dua jendela baru:
masing‑masing menggunakan nama berbeda (Chat 1 dan Chat 2) pada satu channel yang
sama,
tetapi nama channel tersebut dibuat acak setiap kali tombol diklik sehingga sesi Anda terisolasi dari
pengguna lain.
File yang dipakai: chat-demo.html. Parameter query ?name=Chat+1 dan
?name=Chat+2
hanya mengisi nama default di input, sedangkan parameter ?room=chat.demo.<random> dibuat
acak setiap klik.
8. Mengirim Event dari Backend dengan curl
Selain dari frontend, Anda bisa mem-publish event ke channel Notif langsung dari backend menggunakan HTTP
API
POST /api/broadcast. Contoh di bawah ini menggunakan curl (bisa diadaptasi ke
bahasa backend apa pun).
8.1. Contoh kirim ke channel publik
-H "Content-Type: application/json" \
-H "x-app-key: YOUR_APP_KEY" \
-d '{
"channel": "public-demo",
"event": "demo.notification",
"data": { "message": "Hello from backend" }
}'
8.2. Contoh kirim ke channel per-user
Misal backend Anda mengirim ke channel user.123 (ID user = 123):
-H "Content-Type: application/json" \
-H "x-app-key: YOUR_APP_KEY" \
-d '{
"channel": "user.123",
"event": "user.notification",
"data": { "title": "Halo", "body": "Notifikasi dari backend" }
}'
Ganti YOUR_APP_KEY dengan App Key dari halaman Domains di Dashboard. Struktur body JSON sama
seperti ketika Anda memanggil endpoint ini dari JavaScript.