// backend/realtime.jsw import { publish } from 'wix-realtime'; /** * Broadcast a payload to everyone in a chat room. * Channel naming: room: */ export function broadcast(roomId, payload) { return publish(`room:${roomId}`, payload); }
top of page

Designed with You in Mind

Our passion is helping entrepreneurs take their business to the next level using automation. With our DIY website and funnel build-out guidebook, we provide you with the necessary tools to drive sales and scale your business, without breaking the bank. Our guidebook is designed to show you how to leverage automation and technology to streamline your business operations. We’ve done the heavy lifting so that you can focus on what you do best - growing your business! For ONLY $39!

I need this
bottom of page
// backend/data.js import { broadcast } from 'backend/realtime'; /** * Fires after a document is inserted into the Messages collection * (Collection name: Messages -> function name: Messages_afterInsert) */ export function Messages_afterInsert(item, context) { // Keep the payload lean; it's sent to all subscribers. const payload = { _id: item._id, text: item.text, userId: item.userId, userName: item.userName, roomId: item.roomId, createdAt: item.createdAt }; // Fire-and-forget broadcast; don't block the insert lifecycle. broadcast(item.roomId, payload); return item; } // backend/data.js import { broadcast } from 'backend/realtime'; /** * Fires after a document is inserted into the Messages collection * (Collection name: Messages -> function name: Messages_afterInsert) */ export function Messages_afterInsert(item, context) { // Keep the payload lean; it's sent to all subscribers. const payload = { _id: item._id, text: item.text, userId: item.userId, userName: item.userName, roomId: item.roomId, createdAt: item.createdAt }; // Fire-and-forget broadcast; don't block the insert lifecycle. broadcast(item.roomId, payload); return item; } // Page code (e.g., Chat page) import wixData from 'wix-data'; import wixUsers from 'wix-users'; import { subscribe, unsubscribe } from 'wix-realtime'; // If you use Wix Members profile names, you can also import: // import { currentMember } from 'wix-members'; let roomId = 'global'; // default room (or drive from #roomPicker) let myUser = null; let realtimeSub = null; $w.onReady(async () => { myUser = wixUsers.currentUser; initRepeaterItemUI(); await loadMessages(); // Realtime subscribe resubscribe(); // Send message $w('#sendButton').onClick(sendCurrentMessage); $w('#messageInput').onKeyPress((e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendCurrentMessage(); } }); // Optional: switch rooms if ($w('#roomPicker')) { $w('#roomPicker').onChange(async () => { roomId = $w('#roomPicker').value; await loadMessages(); resubscribe(); }); } }); function initRepeaterItemUI() { $w('#messagesRepeater').onItemReady(($item, itemData) => { const mine = itemData.userId === (myUser?.id ?? 'anon'); // Hide both by default, then show one $item('#leftBubble').collapse(); $item('#rightBubble').collapse(); if (mine) { $item('#rightText').text = itemData.text || ''; $item('#rightMeta').text = metaText(itemData); $item('#rightBubble').expand(); } else { $item('#leftText').text = itemData.text || ''; $item('#leftMeta').text = metaText(itemData); $item('#leftBubble').expand(); } }); } function metaText(item) { const name = item.userName || (item.userId ? `User ${item.userId.slice(0,6)}` : 'User'); const ts = item.createdAt ? new Date(item.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : ''; return `${name} • ${ts}`; } async function loadMessages() { const results = await wixData.query('Messages') .eq('roomId', roomId) .ascending('createdAt') .limit(200) // adjust / paginate as needed .find(); $w('#messagesRepeater').data = results.items; focusInput(); } function focusInput() { setTimeout(() => { if ($w('#messageInput')) $w('#messageInput').focus(); }, 50); } async function sendCurrentMessage() { const text = ($w('#messageInput').value || '').trim(); if (!text) return; const item = { text, userId: myUser?.id || 'anon', userName: await getDisplayName(), // or null roomId // createdAt is auto-set in the collection (Default: Now) }; await wixData.insert('Messages', item); // Triggers afterInsert -> broadcast $w('#messageInput').value = ''; } async function getDisplayName() { // Option A (simple): use email local-part if available try { if (myUser?.loggedIn) { const email = await myUser.getEmail(); if (email) return email.split('@')[0]; } } catch (e) { /* ignore */ } // Option B (comment in if using Wix Members): // try { // const member = await currentMember.getMember(); // return member?.profile?.nickname || member?.loginEmail || 'Member'; // } catch (e) {} return myUser?.loggedIn ? 'Member' : 'Guest'; } function resubscribe() { // Clean up the previous subscription if any if (realtimeSub) { try { unsubscribe(realtimeSub); } catch (e) {} realtimeSub = null; } // Subscribe to the current room channel realtimeSub = subscribe(`room:${roomId}`, (message) => { const payload = message?.payload; if (!payload) return; const data = $w('#messagesRepeater').data || []; data.push(payload); $w('#messagesRepeater').data = data; focusInput(); }); }