Menghubungkan Elementor Pro Form ke Google Sheets (Tanpa Plugin Tambahan)

Kode Ini Awalnya Bukan Tentang Kode
Awalnya simpel. Kamu cuma pengin satu hal: setiap ada orang isi form di website, datanya masuk ke Google Sheets. Nggak perlu login WordPress, nggak perlu plugin aneh-aneh. Cukup rapi, cukup kebaca.
Dan jujur aja, kode yang pertama itu sudah ngelakuin tugasnya. Form dikirim, data masuk, beres. Di titik itu, semuanya kelihatan aman.
Masalahnya, sistem digital jarang berhenti di situ.
Ketika Form Mulai Jadi Bagian dari Operasional
Pelan-pelan, form yang tadinya cuma “contact” mulai jadi alat kerja. Ada booking, ada request, ada data yang harus dicek tiap hari. Sheets yang tadinya cuma tempat numpuk data, sekarang jadi pusat informasi.
Di sini kamu mulai sadar: yang kamu butuhin bukan sekadar form yang masuk, tapi sistem yang bisa kamu percaya. Sistem yang nggak bikin kamu deg-degan tiap kali ada perubahan kecil.
Di Dunia Nyata, Data Jarang Datang dengan Rapi
Di atas kertas, semua terlihat lurus. Tapi di dunia nyata, user nggak selalu nurut. Ada field kosong, ada input aneh, ada struktur data yang berubah tanpa permisi. Kadang cuma satu field ditambah, tapi efeknya bisa kemana-mana.
Kode yang bagus itu bukan yang cuma jalan saat kondisi ideal. Tapi yang masih berdiri saat kondisi nggak sempurna. Di sinilah peran struktur yang lebih matang terasa. Bukan buat gaya-gayaan, tapi biar sistem tetap waras.
Kenapa Alur Itu Penting, Bahkan untuk Hal Kecil
Setiap data yang masuk sebenarnya lagi lewat satu alur. Dari form, ke webhook, ke script, lalu ke spreadsheet. Kalau alurnya jelas, kamu tenang. Kalau alurnya berantakan, masalahnya datang pelan-pelan.
Versi kode ini dibikin dengan satu tujuan: supaya alurnya bisa diikuti. Bukan cuma oleh mesin, tapi juga oleh manusia. Jadi saat kamu buka lagi enam bulan kemudian, kamu masih ngerti apa yang terjadi.
Sistem yang Baik Itu Diam, Tapi Bisa Diandalkan
Kamu mungkin nggak sadar saat semuanya berjalan normal. Dan memang seharusnya begitu. Sistem yang baik itu kerja di belakang layar, nggak ribut, nggak minta perhatian.
Tapi saat ada yang salah, dia ngasih sinyal. Bukan pura-pura aman. Bukan diem. Sekadar bilang, “Eh, ada yang perlu dicek.”
Dan percaya atau tidak, itu bikin beda besar di pengalaman kamu sebagai pengguna sistemnya sendiri.
Dari Sekadar Form, Jadi Fondasi
Di titik tertentu, kamu bakal kepikiran buat nyambungin ini ke hal lain. Mungkin ke WhatsApp. Mungkin ke dashboard. Mungkin ke automation. Dan tiba-tiba, form ini bukan cuma form lagi. Dia jadi pintu masuk ke sistem yang lebih besar.
Makanya fondasinya perlu cukup kuat. Bukan harus rumit, tapi cukup siap. Versi kode ini dibuat dengan asumsi bahwa sistemmu akan tumbuh, bukan berhenti hari ini.
Ini Bukan Tentang Lebih Canggih, Tapi Lebih Tenang
Kalau ditanya apa bedanya, jawabanku simpel. Versi ini bukan bikin sistemmu kelihatan lebih canggih. Tapi bikin kamu lebih tenang.
Tenang saat ada perubahan.
Tenang saat data makin banyak.
Tenang saat sistem mulai dipakai beneran.
Dan di dunia digital, rasa tenang itu mahal.
Kode Bisa Anda Dapatkan Dibawah ini!
/**
* ============================================================
* rakapujo.com — Elementor Form → Google Sheets Webhook
* ============================================================
* Purpose:
* - Receive Elementor Pro Form webhook
* - Normalize & flatten form data
* - Auto-create sheet based on form_name
* - Auto-generate headers
* - Store submissions in Google Sheets
*
* Use Case:
* - Digital office
* - Lead collection
* - Booking system
* - Lightweight internal database
*
* Author : rakapujo.com
* License : Internal / Client Use
* ============================================================
*/
/* =========================
CONFIGURATION
========================= */
var ENABLE_EMAIL_NOTIFICATION = false; // true / false
var NOTIFICATION_EMAIL = "youremail@email.com";
/* =========================
SYSTEM FLAGS (DO NOT EDIT)
========================= */
var isNewSheet = false;
/* =========================
WEBHOOK HANDLERS
========================= */
// Required for Web App (GET)
function doGet(e) {
return HtmlService.createHtmlOutput(
"rakapujo.com webhook endpoint — active"
);
}
// Webhook receiver (POST from Elementor)
function doPost(e) {
try {
var payload = JSON.parse(JSON.stringify(e.parameter));
insertToSheet(payload);
return HtmlService.createHtmlOutput(
"Submission received & processed"
);
} catch (err) {
return HtmlService.createHtmlOutput(
"Error: " + err.message
);
}
}
/* =========================
CORE FUNCTIONS
========================= */
// Flatten nested objects (Elementor sends nested params)
function flattenObject(obj, parent, res) {
res = res || {};
for (var key in obj) {
if (!obj.hasOwnProperty(key)) continue;
var propName = parent ? parent + "." + key : key;
if (typeof obj[key] === "object") {
flattenObject(obj[key], propName, res);
} else {
res[propName] = obj[key];
}
}
return res;
}
// Get or create sheet by form_name
function getFormSheet(formName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(formName);
if (!sheet) {
sheet = ss.insertSheet(formName);
isNewSheet = true;
}
return sheet;
}
// Build headers dynamically
function getHeaders(sheet, keys) {
var headers = [];
if (!isNewSheet) {
headers = sheet
.getRange(1, 1, 1, sheet.getLastColumn())
.getValues()[0];
}
keys.forEach(function (key) {
if (headers.indexOf(key) === -1) {
headers.push(key);
}
});
return headers;
}
// Align values with headers
function getRowValues(headers, flatData) {
return headers.map(function (header) {
return flatData[header] || "";
});
}
// Write header row
function setHeaders(sheet, headers) {
var range = sheet.getRange(1, 1, 1, headers.length);
range.setValues([headers]);
range.setFontWeight("bold");
range.setHorizontalAlignment("center");
}
// Insert submission row
function insertRow(sheet, values) {
var lastRow = Math.max(sheet.getLastRow(), 1);
sheet.insertRowAfter(lastRow);
sheet
.getRange(lastRow + 1, 1, 1, values.length)
.setValues([values])
.setHorizontalAlignment("center");
}
// Main insert logic
function insertToSheet(data) {
var flatData = flattenObject(data);
var keys = Object.keys(flatData);
var formName = data.form_name || "Elementor_Form";
var sheet = getFormSheet(formName);
var headers = getHeaders(sheet, keys);
var rowValues = getRowValues(headers, flatData);
setHeaders(sheet, headers);
insertRow(sheet, rowValues);
if (ENABLE_EMAIL_NOTIFICATION) {
sendNotification(formName, getSheetUrl());
}
}
/* =========================
OPTIONAL EMAIL NOTIFICATION
========================= */
function getSheetUrl() {
return SpreadsheetApp.getActiveSpreadsheet().getUrl();
}
function sendNotification(formName, url) {
var subject = "New Form Submission — " + formName;
var body =
"A new submission has been received.\n\n" +
"Form : " + formName + "\n" +
"Sheet : " + url + "\n\n" +
"— rakapujo.com system";
MailApp.sendEmail(NOTIFICATION_EMAIL, subject, body, {
name: "rakapujo.com Automation"
});
}
Terima kasih sudah membaca. Bagikan artikel ini jika bermanfaat!