Status Sinkronisasi
🟢 Aktif Realtime Otomatis mengirim data saat ada transaksiGoogle Sheets Real-time Integration
Dashboard > Integrasi & Database > Google Sheets
Sinkronisasi data Pesanan, Transfer Uang, Produk, dan Pelanggan secara otomatis dan realtime ke spreadsheet.Total Data Tersinkron
0 Data Terakhir: Belum pernahRespon Backend API
~120 ms Serverless Edge DeliverySheet Terhubung
4 Sheet Pesanan, Transfer, Produk, PelangganIntegrasi Google Cloud API (Service Account)
Metode resmi enterprise Google Sheets API v4 menggunakan file Service Account JSON Key.
Pengaturan Koneksi Google Sheets
Hubungkan website Maulana Group dengan Google Apps Script Web App Anda.
Sinkronisasi Masal ke Google Sheets
Kirim seluruh database lokal saat ini langsung ke lembar spreadsheet masing-masing.
Sheet 'Pesanan'
Kirim semua daftar transaksi belanja pelanggan beserta item dan status pembayaran.
Sheet 'Transfer_Uang'
Kirim riwayat transfer uang pelanggan (ID transaksi, bank, nominal, status verified/pending).
Sheet 'Produk'
Kirim katalog produk, harga promo, kategori, satuan, dan jumlah stok terkini.
Sheet 'Pelanggan'
Kirim database akun pembeli dan kontak WhatsApp pengguna terdaftar.
Live Activity Streaming Log
Memantau setiap pengiriman data realtime ke Google Sheets.
| Waktu | Sheet Tujuan | ID Data | Aksi | Status | Durasi | Detail Pesan |
|---|---|---|---|---|---|---|
| Belum ada aktivitas sinkronisasi. Log akan muncul saat ada transaksi. | ||||||
Cara Setup Google Sheets & Apps Script (1-Menit)
Ikuti 3 langkah mudah berikut untuk mengaktifkan sinkronisasi otomatis.
Buat Google Spreadsheet Baru
Buka sheets.new di browser Anda, lalu beri nama spreadsheet "Maulana Group - Database Realtime".
Buka Menu Apps Script
Klik menu Ekstensi (Extensions) > Apps Script di toolbar Google Sheets.
Salin & Tempel Kode di Bawah Ini:
Ganti seluruh isi file Code.gs dengan kode di bawah, lalu klik Simpan.
// ================================================================
// MAULANA GROUP - 2-WAY REAL-TIME GOOGLE SHEETS BACKEND ENGINE
// ================================================================
// 1. PULL (TARIK DATA DARI GOOGLE SHEETS KE WEBSITE)
function doGet(e) {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = (e && e.parameter && e.parameter.sheet) ? e.parameter.sheet : null;
var result = {};
if (sheetName) {
var s = ss.getSheetByName(sheetName);
result[sheetName] = s ? readSheetRows(s) : [];
} else {
var sheets = ss.getSheets();
sheets.forEach(function(s) {
result[s.getName()] = readSheetRows(s);
});
}
return ContentService.createTextOutput(JSON.stringify({
success: true,
timestamp: new Date().toISOString(),
data: result
})).setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({
success: false,
error: err.toString()
})).setMimeType(ContentService.MimeType.JSON);
}
}
function readSheetRows(sheet) {
var data = sheet.getDataRange().getValues();
if (!data || data.length === 0) return [];
// Cari baris mana yang merupakan header kolom sebenarnya (baris dengan teks terbanyak)
var headerRowIdx = 0;
var maxCols = 0;
for (var r = 0; r < Math.min(5, data.length); r++) {
var count = 0;
for (var c = 0; c < data[r].length; c++) {
if (data[r][c] !== "" && data[r][c] !== null && data[r][c] !== undefined) count++;
}
if (count > maxCols) {
maxCols = count;
headerRowIdx = r;
}
}
// Hitung total kolom maksimal
var totalCols = 0;
for (var r = 0; r < data.length; r++) {
if (data[r].length > totalCols) totalCols = data[r].length;
}
// Siapkan nama header (A, B, C, D atau teks judul kolom)
var headers = [];
for (var c = 0; c < totalCols; c++) {
var hVal = data[headerRowIdx] && data[headerRowIdx][c] ? String(data[headerRowIdx][c]).trim() : "";
if (!hVal || headers.indexOf(hVal) !== -1) {
var colLetter = String.fromCharCode(65 + (c % 26));
hVal = hVal ? (hVal + " (" + colLetter + ")") : ("Kolom " + colLetter);
}
headers.push(hVal);
}
var rows = [];
for (var i = headerRowIdx + 1; i < data.length; i++) {
var row = data[i];
var item = {};
var hasVal = false;
for (var j = 0; j < totalCols; j++) {
var key = headers[j];
var val = (row && row[j] !== undefined && row[j] !== null) ? row[j] : "";
item[key] = val;
if (val !== "" && val !== null && val !== undefined) hasVal = true;
}
if (hasVal) rows.push(item);
}
return rows;
}
// 2. PUSH (KIRIM DATA DARI WEBSITE KE GOOGLE SHEETS)
function doPost(e) {
try {
var rawData = e.postData.contents;
var payload = JSON.parse(rawData);
var sheetName = payload.sheet || "General";
var action = payload.action || "sync";
var data = payload.data;
var timestamp = payload.timestamp || new Date().toISOString();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
if (!sheet) {
sheet = ss.insertSheet(sheetName);
setupSheetHeaders(sheet, sheetName);
}
if (Array.isArray(data)) {
data.forEach(function(item) {
appendRecord(sheet, sheetName, item, timestamp);
});
} else {
appendRecord(sheet, sheetName, data, timestamp);
}
return ContentService.createTextOutput(JSON.stringify({
success: true,
message: "Data berhasil dicatat ke sheet " + sheetName,
timestamp: new Date().toISOString()
})).setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({
success: false,
error: err.toString()
})).setMimeType(ContentService.MimeType.JSON);
}
}
function appendRecord(sheet, sheetName, item, timestamp) {
if (sheetName === "Transfer_Uang") {
sheet.appendRow([
item.id || "-",
timestamp,
item.senderName || "-",
item.senderWhatsApp || "-",
item.bank || "-",
item.account || "-",
item.recipientName || "-",
item.phone || "-",
item.amount || 0,
item.totalLabel || "-",
item.status || "pending"
]);
} else if (sheetName === "Pesanan") {
sheet.appendRow([
item.id || item.orderId || "-",
timestamp,
item.customerName || item.recipientName || "-",
item.phone || item.whatsapp || "-",
item.total || item.totalPrice || 0,
item.paymentMethod || "Transfer Bank",
item.status || "Menunggu Pembayaran",
JSON.stringify(item.items || [])
]);
} else if (sheetName === "Produk") {
sheet.appendRow([
item.id || "-",
timestamp,
item.name || "-",
item.category || "-",
item.price || 0,
item.stock || 0,
item.unit || "pcs"
]);
} else {
sheet.appendRow([timestamp, JSON.stringify(item)]);
}
}
function setupSheetHeaders(sheet, sheetName) {
sheet.setTabColor("#008a4b");
var headerRange;
if (sheetName === "Transfer_Uang") {
sheet.appendRow([
"ID Invoice", "Waktu Transaksi", "Nama Pengirim", "WA Pengirim",
"Bank Tujuan", "No. Rekening", "Nama Penerima", "No. HP Penerima",
"Nominal (Rp)", "Total Pembayaran", "Status Verifikasi"
]);
} else if (sheetName === "Pesanan") {
sheet.appendRow([
"ID Pesanan", "Waktu Pesanan", "Nama Pelanggan", "No. WhatsApp",
"Total Belanja", "Metode Pembayaran", "Status Pesanan", "Detail Item"
]);
} else if (sheetName === "Produk") {
sheet.appendRow([
"ID Produk", "Waktu Update", "Nama Produk", "Kategori",
"Harga (Rp)", "Stok", "Satuan"
]);
} else {
sheet.appendRow(["Waktu", "Payload Data"]);
}
headerRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
headerRange.setBackground("#008a4b").setFontColor("#ffffff").setFontWeight("bold");
}
Deploy Web App
Klik tombol biru Deploy > New deployment di pojok kanan atas Apps Script.
- Pilih tipe: Web app
- Execute as: Me
- Who has access: Anyone (Semua orang)
- Klik Deploy dan salin Web app URL ke formulir Tab 1 di atas!