🔧 Langkah 1: Buat Google Sheets
- Buka Google Sheets
- Buat spreadsheet baru dengan nama "Hasil Ujian OMI Ekonomi"
- Buat header di baris pertama: Timestamp, Nama, Kategori, Percobaan, Benar, Salah, Nilai, Detail_Jawaban
⚙️ Langkah 2: Buat Google Apps Script
- Di Google Sheets, klik Extensions → Apps Script
- Hapus kode default dan copy-paste kode berikut:
function doPost(e) {
try {
Logger.log('=== MULAI doPost ===');
Logger.log('Request received at: ' + new Date());
var data = {};
// Method 1: Coba parse JSON dari postData
if (e.postData && e.postData.contents) {
Logger.log('Method 1: Parsing JSON dari postData');
Logger.log('Content type: ' + e.postData.type);
Logger.log('Raw contents: ' + e.postData.contents);
try {
data = JSON.parse(e.postData.contents);
Logger.log('JSON parsing berhasil');
} catch (parseError) {
Logger.log('JSON parsing gagal: ' + parseError.toString());
throw new Error('Format JSON tidak valid: ' + parseError.toString());
}
}
// Method 2: Coba ambil dari parameter
else if (e.parameter) {
Logger.log('Method 2: Menggunakan parameter');
if (e.parameter.data) {
Logger.log('Parsing data dari parameter.data');
try {
data = JSON.parse(e.parameter.data);
} catch (parseError) {
Logger.log('Parameter JSON parsing gagal: ' + parseError.toString());
data = e.parameter;
}
} else {
Logger.log('Menggunakan parameter langsung');
data = e.parameter;
}
}
// Method 3: Tidak ada data
else {
Logger.log('Method 3: Tidak ada data diterima');
throw new Error('Tidak ada data yang diterima dari request');
}
Logger.log('Data yang akan diproses: ' + JSON.stringify(data));
// Validasi data minimal
if (!data.nama && !data.test) {
throw new Error('Data tidak lengkap - nama atau test harus ada');
}
// Dapatkan spreadsheet aktif
var sheet;
try {
sheet = SpreadsheetApp.getActiveSheet();
Logger.log('Menggunakan sheet aktif: ' + sheet.getName());
} catch (sheetError) {
Logger.log('Gagal mendapatkan sheet aktif: ' + sheetError.toString());
throw new Error('Tidak dapat mengakses Google Sheets. Pastikan script terhubung dengan spreadsheet.');
}
// Setup header jika sheet kosong
var lastRow = sheet.getLastRow();
Logger.log('Jumlah baris terakhir: ' + lastRow);
if (lastRow === 0) {
Logger.log('Sheet kosong, menambahkan header');
var headers = ['Timestamp', 'Nama', 'Kategori', 'Percobaan', 'Benar', 'Salah', 'Nilai', 'Detail_Jawaban'];
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
// Format header
var headerRange = sheet.getRange(1, 1, 1, headers.length);
headerRange.setFontWeight('bold');
headerRange.setBackground('#e3f2fd');
}
// Siapkan data untuk ditambahkan
var rowData = [
new Date(),
data.nama || 'Test User',
data.kategori || 'Test Category',
parseInt(data.percobaan) || 1,
parseInt(data.benar) || 0,
parseInt(data.salah) || 0,
parseInt(data.nilai) || 0,
JSON.stringify(data.detail_jawaban || {})
];
Logger.log('Data yang akan ditambahkan: ' + JSON.stringify(rowData));
// Tambahkan data ke sheet
sheet.appendRow(rowData);
Logger.log('Data berhasil ditambahkan ke baris: ' + (sheet.getLastRow()));
// Response sukses
var response = {
success: true,
result: 'success',
message: 'Data berhasil disimpan ke Google Sheets',
timestamp: new Date().toISOString(),
rowNumber: sheet.getLastRow(),
sheetName: sheet.getName()
};
Logger.log('Response: ' + JSON.stringify(response));
Logger.log('=== SELESAI doPost (SUKSES) ===');
return ContentService
.createTextOutput(JSON.stringify(response))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
Logger.log('=== ERROR di doPost ===');
Logger.log('Error: ' + error.toString());
Logger.log('Stack: ' + error.stack);
var errorResponse = {
success: false,
error: error.toString(),
message: 'Gagal menyimpan data: ' + error.toString(),
timestamp: new Date().toISOString()
};
Logger.log('Error response: ' + JSON.stringify(errorResponse));
Logger.log('=== SELESAI doPost (ERROR) ===');
return ContentService
.createTextOutput(JSON.stringify(errorResponse))
.setMimeType(ContentService.MimeType.JSON);
}
}
function doGet(e) {
try {
Logger.log('=== doGet dipanggil ===');
Logger.log('Parameters: ' + JSON.stringify(e.parameter));
var response = {
success: true,
result: 'success',
message: 'Google Apps Script berjalan dengan baik!',
timestamp: new Date().toISOString(),
method: 'GET'
};
Logger.log('GET Response: ' + JSON.stringify(response));
return ContentService
.createTextOutput(JSON.stringify(response))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
Logger.log('Error di doGet: ' + error.toString());
return ContentService
.createTextOutput(JSON.stringify({
success: false,
error: error.toString(),
message: 'Error di doGet: ' + error.toString()
}))
.setMimeType(ContentService.MimeType.JSON);
}
}
// Function untuk test manual
function testManual() {
Logger.log('=== TEST MANUAL ===');
try {
var sheet = SpreadsheetApp.getActiveSheet();
Logger.log('Sheet name: ' + sheet.getName());
Logger.log('Last row: ' + sheet.getLastRow());
// Test data
var testData = {
nama: 'Test Manual ' + new Date().getTime(),
kategori: 'Test Category',
percobaan: 1,
benar: 5,
salah: 3,
nilai: 50,
detail_jawaban: {test: 'data'}
};
// Simulasi doPost
var mockEvent = {
postData: {
contents: JSON.stringify(testData),
type: 'application/json'
}
};
var result = doPost(mockEvent);
Logger.log('Test result: ' + result.getContent());
return 'Test berhasil! Cek log untuk detail.';
} catch (error) {
Logger.log('Test error: ' + error.toString());
return 'Test gagal: ' + error.toString();
}
}
🚀 Langkah 3: Deploy Script
- Klik "Deploy" → "New deployment"
- Type: pilih "Web app"
- Execute as: "Me"
- Who has access: "Anyone"
- Klik "Deploy" dan copy URL yang diberikan
- Paste URL tersebut ke field di atas dan klik "Simpan URL"
⚠️ Troubleshooting Koneksi Gagal
🔍 LANGKAH WAJIB - Ikuti urutan ini:
- Buat Google Sheets baru dengan nama "Hasil Ujian OMI Ekonomi"
- Di Sheets tersebut: Extensions → Apps Script
- Hapus semua kode dan paste kode yang disediakan di atas
- Klik Save (Ctrl+S) dan beri nama project "OMI Ekonomi Script"
- Klik Deploy → New deployment
- Pilih Type: Web app
- Execute as: Me (your email)
- Who has access: Anyone
- Klik Deploy dan authorize jika diminta
- Copy URL yang berakhiran "/exec" (BUKAN "/dev")
- Paste URL di field di atas dan klik "Simpan URL"
- Klik "Test Koneksi" untuk memastikan berhasil
🚨 Kesalahan Umum:
- URL salah: Harus berakhiran "/exec" bukan "/dev"
- Permission salah: Harus "Anyone" bukan "Anyone with Google account"
- Script belum di-save: Tekan Ctrl+S sebelum deploy
- Belum authorize: Klik "Review permissions" saat deploy
- Sheets di-protect: Pastikan sheets bisa diedit
💡 Tips Tambahan:
- Gunakan akun Google yang sama untuk Sheets dan Apps Script
- Jika masih error, coba buka URL script di browser baru (incognito)
- Pastikan tidak ada popup blocker yang menghalangi
- Coba logout dan login ulang ke Google account
- Jika tetap gagal, buat project Apps Script yang benar-benar baru
✅ Cara Memastikan Berhasil:
- Test koneksi menunjukkan "✅ Koneksi berhasil!"
- Ada data test baru di Google Sheets
- Tidak ada error message berwarna merah
- URL berakhiran "/exec" dan dimulai dengan "https://script.google.com/macros/s/"