Senin, 15 Desember 2025

Apps Script 1 - Google Apps Script

 



Apa itu Google Apps Script (GAS)

Google Apps Script adalah platform scripting berbasis JavaScript yang digunakan untuk mengotomasi dan mengintegrasikan layanan Google Workspace, seperti:

  • Google Sheets

  • Google Docs

  • Google Forms

  • Gmail

  • Google Drive

  • Calendar

  • Dan API eksternal (REST API)

๐Ÿ“Œ GAS berjalan di cloud Google, tanpa perlu server sendiri.


Karakteristik Teknis

  • Bahasa: JavaScript (ES5–ES6 sebagian)

  • Runtime: V8 Engine

  • Paradigma: Procedural + Object-oriented

  • Akses API Google native (tanpa OAuth manual untuk internal)


Contoh Dasar: Hello World

function helloWorld() { Logger.log("Hello Google Apps Script"); }

๐Ÿ“ Jalankan → lihat di Executions Log


Contoh Praktis: Otomasi Google Sheets

Membaca & menulis data

function readWriteSheet() { const sheet = SpreadsheetApp .getActiveSpreadsheet() .getActiveSheet(); sheet.getRange("A1").setValue("Belajar GAS"); }

Contoh: Otomasi Gmail

function sendEmail() { GmailApp.sendEmail( "email@contoh.com", "Belajar Google Apps Script", "Ini email dikirim otomatis dari GAS" ); }

Contoh: Trigger Otomatis (Cron)

function dailyJob() { Logger.log("Job harian berjalan"); }

➡️ Triggers → Time-driven → Daily


Contoh: Web App (API Endpoint)

function doGet(e) { return ContentService .createTextOutput(JSON.stringify({ status: "success", message: "Hello API" })) .setMimeType(ContentService.MimeType.JSON); }

๐Ÿ“Œ Bisa dijadikan:

  • Backend ringan

  • API untuk frontend

  • Integrasi sistem sekolah / UMKM


Struktur Proyek GAS

  • Code.gs → file utama

  • .gs lain → modular

  • appsscript.json → konfigurasi & scopes


Use Case yang Cocok untuk Anda

Sebagai programmer & trainer digital skills, GAS sangat cocok untuk:

  • ๐Ÿ“Š Dashboard laporan otomatis (Sheets → PDF → Email)

  • ๐Ÿงพ Form → Approval → Email notifikasi

  • ๐Ÿ“ Upload & manajemen Drive otomatis

  • ๐Ÿ”— Integrasi dengan REST API (WhatsApp, payment, LMS)

  • ⚙️ Backend ringan tanpa server (untuk MVP)


Roadmap Belajar GAS (Disarankan)

1️⃣ Dasar JavaScript di GAS
2️⃣ SpreadsheetApp & DriveApp
3️⃣ Trigger & permission
4️⃣ Gmail & Form automation
5️⃣ Web App & REST API
6️⃣ Best practice & security
7️⃣ Studi kasus nyata (laporan, approval, dashboard)


Studi Kasus Nyata (Contoh)

Sistem Laporan Digital Skills

  • Input data via Google Form

  • Data masuk Sheets

  • Otomatis rekap

  • Generate PDF

  • Kirim ke email Dinas / UNICEF


Jika Anda mau, saya bisa:

  • ✅ Buat modul belajar GAS bertahap

  • ✅ Buat studi kasus real (pendidikan / UMKM / laporan)

  • ✅ Buat template script siap pakai

  • ✅ Bandingkan GAS vs PHP / Node.js


Baik, saya jelaskan secara terstruktur dan teknis karena ini sudah level aplikasi web lengkap berbasis Google Apps Script (GAS) dengan role-based access control (RBAC) dan CRUD.

Script ini membangun Web App “SISKO DB – Sistem Informasi Sekolah” dengan Google Spreadsheet sebagai database dan Google Drive sebagai storage foto.


1. KONFIGURASI GLOBAL

var SPREADSHEET_ID = 'UBAH'; var FOLDER_ID = 'UBAH';

Fungsi

  • SPREADSHEET_IDdatabase utama (Google Sheet)

  • FOLDER_IDfolder Drive untuk menyimpan foto siswa

๐Ÿ“Œ Wajib diganti agar aplikasi berjalan.


2. ENTRY POINT WEB APP

function doGet(e) { return HtmlService.createHtmlOutputFromFile('index')

Fungsi

  • Endpoint utama Web App

  • Menampilkan file index.html

  • Bertindak seperti index.php / index.js pada web biasa

Konfigurasi tambahan

.setTitle('Sistem Informasi Sekolah (SISKO DB)') .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) .addMetaTag("viewport", "width=device-width, initial-scale=1.0") .setFaviconUrl(...)

➡️ Optimasi UI, mobile friendly, bisa di-embed iframe.


3. LOGIN & AUTENTIKASI

function login(username, password)

Alur

  1. Buka Spreadsheet

  2. Ambil sheet Users

  3. Loop data user

  4. Cocokkan username & password

Struktur Sheet Users

usernamepasswordrolenisnnama_lengkap

Role

  • Admin → full akses

  • Guru → akses berdasarkan kelas & jurusan

  • Siswa → hanya datanya sendiri

Optimasi Penting

var initialDataSiswa = getData(userRole, userNisn).data || [];

๐Ÿ“Œ Preload data siswa saat login
➡️ Mengurangi request dari frontend

Output ke Frontend

{ success: true, role: "Guru", nisn: "101", nama: "Pak Joko", initialData: [...] }

4. GET DATA SISWA (ROLE BASED)

function getData(role, nisn)

Fungsi Inti Aplikasi

Mengontrol hak akses data siswa berdasarkan role.


4.1. Permission Guru

guruPermissions.push({ kelas: gData[g][3], jurusan: gData[g][4] });

๐Ÿ“Œ Guru bisa mengajar:

  • kelas tertentu

  • jurusan tertentu

  • jurusan Umum / Semua


4.2. Format Data

var row = { timestamp, nama, nisn, kelas, jurusan, alamat, fotoUrl };

Tanggal diformat manual

Utilities.formatDate(...)

4.3. Filter Berdasarkan Role

Admin

result.push(row);

➡️ Lihat semua data

Siswa

if (data[i][2] == nisn)

➡️ Lihat data sendiri

Guru

kelasMatch && jurusanMatch

➡️ Lihat siswa sesuai izin mengajar

๐Ÿ“Œ Ini RBAC (Role-Based Access Control) versi GAS.


5. CRUD DATA SISWA

Tambah

function addData(obj)
  • Cek duplikat NISN

  • Append ke sheet

Update

function updateData(obj)
  • Cari berdasarkan NISN

  • Update kolom tertentu

Delete

function deleteData(nisn)
  • Hapus row langsung

๐Ÿ“Œ Spreadsheet berperan sebagai database tabel tunggal.


6. CRUD DATA GURU

getGuruData()

Ambil semua guru

addGuru()

  • Buat sheet jika belum ada

  • Cek duplikat NIP

updateGuru()

Update berdasarkan NIP

deleteGuru()

Delete row guru

➡️ Mirip master data table di sistem akademik.


7. RELASI SISWA – GURU

function getTeachersByStudent(kelasSiswa, jurusanSiswa)

Logika

Guru cocok jika:

  • Kelas sama

  • Jurusan sama atau Umum / Semua

๐Ÿ“Œ Ini semacam JOIN manual antara DataSiswa dan DataGuru.


8. UPLOAD FOTO (GOOGLE DRIVE)

function uploadImage(base64, filename)

Alur

  1. Decode Base64

  2. Buat Blob

  3. Simpan ke Drive

  4. Share public

  5. Convert ke direct image URL

https://lh3.googleusercontent.com/d/FILE_ID

๐Ÿ“Œ Hack penting agar gambar bisa ditampilkan di <img> HTML.


9. HELPER URL GAMBAR

function processImageUrl(url)

Fungsi

  • Mengubah link Drive lama

  • Jadi format direct display

➡️ Menangani kompatibilitas data lama.


10. INITIALIZE DATABASE (MIGRATION SCRIPT)

function initializeSheets()

Fungsi

  • Reset seluruh sistem

  • Buat:

    • Users

    • DataSiswa

    • DataGuru

  • Isi data default

  • Styling header

๐Ÿ“Œ Ini seperti:

  • migration + seeder di Laravel

  • schema.sql + dummy data


11. UPDATE FOTO SISWA SAJA

function updateFotoSiswa(nisn, fotoUrl)

Fungsi

  • Update timestamp

  • Update foto profil saja

๐Ÿ“Œ Optimasi agar tidak update data lain.


12. ARSITEKTUR SISTEM (Ringkas)

Frontend (HTML + JS) ↓ Google Apps Script (API) ↓ Google Spreadsheet (DB) ↓ Google Drive (Image Storage)

13. KESIMPULAN

Script ini adalah:
✅ Web App GAS skala menengah
✅ Sistem akademik mini
✅ Role-based access control
✅ CRUD lengkap
✅ Storage gambar
✅ Siap dipakai untuk sekolah


Index.html

1. PERAN FILE index.html

index.html adalah frontend utama (UI layer) dari Web App Google Apps Script.

Fungsi utamanya:

  • Menyediakan tampilan login

  • Menampilkan dashboard berdasarkan role (Admin / Guru / Siswa)

  • Menjadi client yang memanggil function di Code.gs lewat google.script.run

๐Ÿ“Œ Dalam arsitektur MVC:

  • View + Controller ringan → index.html

  • Model + Controller → Code.gs

  • Database → Google Spreadsheet


2. STRUKTUR UMUM FILE

Secara garis besar, index.html berisi:

<html> ├─ <head> │ ├─ CSS (Bootstrap / style) │ └─ <script> JS frontend └─ <body> ├─ Login Section ├─ Admin Section ├─ Guru Section └─ Siswa Section

Semua halaman ada dalam satu file (Single Page Application sederhana).


3. BAGIAN <head> – UI & STYLE

Biasanya berisi:

<link rel="stylesheet" href="bootstrap.css"> <style> .hidden { display:none; } </style>

Fungsi

  • Styling UI

  • Membuat section bisa ditampilkan/disembunyikan

  • Tidak mempengaruhi logic backend

๐Ÿ“Œ Best practice GAS:
CSS langsung di HTML agar tidak load eksternal berat.


4. LOGIN SECTION

<div id="loginSection"> <input id="username"> <input id="password"> <button onclick="doLogin()">Login</button> </div>

Fungsi

  • Input kredensial user

  • Entry point aplikasi

Kenapa penting?

  • Semua role harus lewat login

  • loginSection akan disembunyikan setelah login sukses


5. FUNGSI doLogin() (CLIENT SIDE)

function doLogin() { google.script.run .withSuccessHandler(handleLogin) .login(username, password); }

Penjelasan

  • google.script.run = bridge frontend → backend

  • .login() memanggil function login() di Code.gs

  • Tidak reload halaman (AJAX-like)

๐Ÿ“Œ Ini bukan HTTP request, tapi RPC internal GAS.


6. HANDLE RESPONSE LOGIN

function handleLogin(res) { if (!res.success) { ... } currentUser = res; }

Response dari backend

{ success: true, role: "Guru", nisn: "101", nama: "Pak Joko", initialData: [...] }

Fungsi handler

  • Menyimpan state user

  • Menentukan UI yang ditampilkan

  • Menyembunyikan login


7. STATE MANAGEMENT FRONTEND

window.currentUser = { role, nisn, nama, initialData }

Fungsi

  • Menyimpan sesi user (client-side)

  • Dipakai ulang oleh:

    • upload foto

    • update data

    • filter UI

๐Ÿ“Œ Ini session palsu, bukan server session.


8. ADMIN SECTION

<div id="adminSection"> <table id="tableSiswa"></table> </div>

Fungsi

  • Tampil hanya jika role === 'Admin'

  • Menampilkan seluruh data siswa

  • CRUD siswa & guru

Data

renderTable(currentUser.initialData);

๐Ÿ“Œ Data sudah dikirim sejak login (optimasi).


9. GURU SECTION

<div id="guruSection"> <table id="tableGuru"></table> </div>

Fungsi

  • Read-only data siswa

  • Data sudah difilter backend berdasarkan:

    • kelas ajar

    • jurusan ajar

๐Ÿ“Œ Keamanan di backend, bukan frontend.


10. SISWA SECTION

<div id="siswaSection"> <img id="fotoProfil"> <input type="file" onchange="uploadFoto(this)"> </div>

Fungsi

  • Menampilkan profil siswa

  • Upload foto

๐Ÿ“Œ Siswa tidak bisa melihat siswa lain


11. RENDER DATA KE HTML

function renderTable(data) { data.forEach(row => { table.innerHTML += `<tr>...</tr>`; }); }

Fungsi

  • Mengubah JSON → HTML

  • Tidak ada manipulasi database di frontend

๐Ÿ“Œ Frontend hanya consumer data.


12. UPLOAD FOTO – CLIENT SIDE

reader.readAsDataURL(file);

Flow

FileBase64GASDriveURLSheet

Frontend:

  • Convert file → Base64

  • Kirim ke uploadImage()

Backend:

  • Simpan ke Drive

  • Return URL


13. KOMUNIKASI FRONTEND ↔ BACKEND

Semua komunikasi memakai:

google.script.run .withSuccessHandler(fn) .backendFunction(param);

๐Ÿ“Œ Tidak bisa pakai:

  • fetch

  • axios

  • XMLHttpRequest

Karena sandbox GAS.


14. KONTROL VISIBILITAS UI

document.getElementById('adminSection').style.display = 'block';

Tujuan

  • Simulasi halaman berbeda

  • Tetap satu HTML

๐Ÿ“Œ SPA versi sederhana.


15. KEAMANAN (CATATAN PENTING)

❌ Password plain text
❌ Session client-side
❌ Bisa di-manipulasi via DevTools

Namun:
✅ Aman untuk internal sekolah
✅ Bukan sistem publik besar


16. RINGKASAN FUNGSI FILE index.html

BagianFungsi
Login UIAutentikasi user
Role SwitchTampilkan dashboard sesuai role
Render DataMenampilkan data dari Sheet
Upload FotoInteraksi Drive
State UserMenyimpan sesi frontend

17. KESIMPULAN

index.html ini:

  • Bertindak sebagai SPA Client

  • Tidak menyimpan data permanen

  • Semua logika kritikal ada di backend

  • Cocok untuk Web App GAS skala menengah


Jika Anda mau, langkah lanjut yang sangat recommended:

  1. ๐Ÿ” Bedah index.html baris per baris

  2. ๐Ÿงฉ Refactor jadi komponen terpisah

  3. ๐Ÿ” Tambahkan login hashing

  4. ๐Ÿ“ฑ Buat versi mobile-first UI





<!-- ================= index.html (ENTRY POINT) ================= -->
<!DOCTYPE html>
<html>
<head>
  <base target="_top">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SISKO DB</title>
  <?!= include('styles'); ?>
</head>
<body>
  <?!= include('header'); ?>

  <main class="container">
    <?!= include('login'); ?>
    <?!= include('admin'); ?>
    <?!= include('guru'); ?>
    <?!= include('siswa'); ?>
  </main>

  <?!= include('app'); ?>
</body>
</html>

<!-- ================= styles.html ================= -->
<style>
  body { font-family: Arial, sans-serif; margin:0; background:#f4f6f9; }
  header { background:#1a73e8; color:#fff; padding:12px 20px; }
  .container { padding:20px; }
  .hidden { display:none; }
  input, button { padding:8px; width:100%; margin:5px 0; }
  button { background:#1a73e8; color:#fff; border:none; cursor:pointer; }
  table { width:100%; border-collapse:collapse; }
  th, td { border:1px solid #ddd; padding:8px; }
</style>

<!-- ================= header.html ================= -->
<header>
  <strong>SISKO DB</strong>
  <span id="userInfo" style="float:right"></span>
</header>

<!-- ================= login.html ================= -->
<section id="view-login">
  <h3>Login</h3>
  <input id="login-username" placeholder="Username">
  <input id="login-password" type="password" placeholder="Password">
  <button onclick="Auth.login()">Login</button>
  <div id="login-message"></div>
</section>

<!-- ================= admin.html ================= -->
<section id="view-admin" class="hidden">
  <h3>Dashboard Admin</h3>
  <div id="admin-table"></div>
</section>

<!-- ================= guru.html ================= -->
<section id="view-guru" class="hidden">
  <h3>Dashboard Guru</h3>
  <div id="guru-table"></div>
</section>

<!-- ================= siswa.html ================= -->
<section id="view-siswa" class="hidden">
  <h3>Profil Siswa</h3>
  <div id="siswa-profile"></div>
  <input type="file" onchange="Siswa.uploadFoto(this)">
</section>

<!-- ================= app.html (JS MODULES) ================= -->
<script>
const AppState = { user:null };

const UI = {
  show(id){ document.querySelectorAll('section').forEach(s=>s.classList.add('hidden')); document.getElementById(id).classList.remove('hidden'); },
  setUser(text){ document.getElementById('userInfo').innerText=text; }
};

const Auth = {
  login(){
    google.script.run.withSuccessHandler(Auth.handleLogin)
      .login(login-username.value, login-password.value);
  },
  handleLogin(res){
    if(!res.success){ login-message.innerText=res.message; return; }
    AppState.user=res;
    UI.setUser(res.nama+' ('+res.role+')');
    if(res.role==='Admin'){ UI.show('view-admin'); }
    if(res.role==='Guru'){ UI.show('view-guru'); }
    if(res.role==='Siswa'){ UI.show('view-siswa'); }
  }
};

const Siswa = {
  uploadFoto(input){ /* sama seperti versi sebelumnya */ }
};
</script>

Penjelasan

1. MASALAH JIKA SATU FILE HTML BESAR

Sebelum split:

  • index.html panjang & sulit dibaca

  • Login, admin, guru, siswa tercampur

  • Sulit maintenance & kolaborasi

  • Tidak scalable

➡️ Solusi profesional:
Partial HTML + include()


2. KONSEP UTAMA: <?!= include('file'); ?>

Di Google Apps Script, kita bisa:

<?!= include('login'); ?>

Artinya:

  • Ambil isi file login.html

  • Render ke index.html

  • Server-side rendering (sebelum dikirim ke browser)

๐Ÿ“Œ Mirip:

  • PHP include()

  • Blade / Twig partial


3. STRUKTUR FILE PROFESIONAL

๐Ÿ“ GAS Project ├─ Code.gs ├─ index.html (entry point) ├─ styles.html (CSS) ├─ header.html (navbar/header) ├─ login.html (login view) ├─ admin.html (admin dashboard) ├─ guru.html (guru dashboard) ├─ siswa.html (siswa dashboard) └─ app.html (JS logic)

๐Ÿ‘‰ Ini standar produksi untuk GAS Web App.


4. index.html → ENTRY POINT

Fungsi:

  • Layout utama

  • Menggabungkan semua partial

<?!= include('styles'); ?> <?!= include('header'); ?> <?!= include('login'); ?> <?!= include('admin'); ?> <?!= include('guru'); ?> <?!= include('siswa'); ?> <?!= include('app'); ?>

๐Ÿ“Œ index.html tidak berisi logic detail, hanya komposisi.


5. styles.html → SEMUA CSS

<style> body { font-family: Arial; } .hidden { display:none; } </style>

Keuntungan

  • CSS terpusat

  • Mudah ganti tema

  • Tidak ganggu JS


6. header.html → UI GLOBAL

<header> <strong>SISKO DB</strong> <span id="userInfo"></span> </header>

Fungsi

  • Header konsisten

  • Menampilkan nama & role user

  • Bisa ditambah logout, menu, dll


7. login.html → LOGIN VIEW

<section id="view-login"> <input id="login-username"> <input id="login-password"> </section>

๐Ÿ“Œ Hanya HTML murni, tanpa logic
➡️ Logic ada di app.html


8. admin.html, guru.html, siswa.html

Masing-masing satu role = satu file.

Contoh admin.html

<section id="view-admin" class="hidden"> <h3>Dashboard Admin</h3> </section>

๐Ÿ“Œ Prinsip:

  • View only

  • Tidak tahu backend

  • Tidak tahu login logic


9. app.html → OTAK APLIKASI (JS)

Semua JavaScript dikumpulkan di sini:

  • State

  • Auth

  • UI control

  • Module siswa

<script> const AppState = { user:null }; const Auth = { login(), handleLogin() }; const UI = { show(), setUser() }; </script>

๐Ÿ“Œ Ini seperti:

  • main.js

  • app.js


10. FLOW APLIKASI SETELAH SPLIT

Browser ↓ index.html ↓ include(partials) ↓ HTML final dikirim ↓ User login ↓ JS (app.html) aktif ↓ google.script.run → Code.gs

๐Ÿ“Œ Split file tidak mempengaruhi performa, karena include terjadi di server.


11. KEUNTUNGAN UTAMA SPLIT FILE

✅ Readable
✅ Maintainable
✅ Mudah dikembangkan
✅ Cocok untuk tim
✅ Standar industri
✅ Tidak ribet seperti React


12. BEST PRACTICE NAMING

FileIsi
login.htmllogin UI
admin.htmladmin view
guru.htmlguru view
siswa.htmlsiswa view
app.htmlJS logic
styles.htmlCSS

13. KESALAHAN UMUM YANG HARUS DIHINDARI

❌ Logic JS di setiap file
❌ CSS di banyak tempat
❌ ID DOM bentrok
❌ Frontend menentukan keamanan


14. SIAP NAIK LEVEL LAGI?

Langkah lanjutan (advance):

  1. ๐Ÿ” Hash password + session token

  2. ๐Ÿ”„ Lazy load data

  3. ๐Ÿ” Search & pagination

  4. ๐Ÿงฉ Component pattern

  5. ๐ŸŒ GAS sebagai REST API

  6. ๐Ÿ“ฑ Mobile-first UI


https://chatgpt.com/c/694081ca-8e94-8321-9d4a-cef313ad7bb0

Tidak ada komentar:

Posting Komentar

Sylabus Struktur Data Using CPP

  https://www.youtube.com/watch?v=PQrkEa5aK3I Minggu Topik Utama Materi Pembahasan 1 Review Dasar C++ & Memory Pointer, reference, alama...