Featured

    Featured Posts

  • dimana kehidupan
  • disitulah jawaban

Belajar Apps Script: Pasang Domain Sendiri Pakai Cloudflare Worker


Sebelumnya sistem antrean konsultasi ini cuma jalan dari link bawaan Google Apps Script. Link-nya panjang, acak, dan jujur saja susah diingat. Saya sendiri saja kalau mau buka harus cari-cari lagi di catatan.

Dari situ muncul keinginan sederhana: pengin punya alamat sendiri yang pendek, misalnya bimbingan.contohdomain.my.id, biar gampang ditulis di pengumuman dan gampang diingat mahasiswa.

Ternyata perjalanan ke sana tidak sesederhana "tinggal ganti alamat". Catatan ini saya tulis supaya langkahnya tidak hilang, karena saya yakin suatu saat saya akan lupa dan butuh membaca ini lagi.

Daftar Isi

  • 1. Gambaran Alurnya Dulu
  • 2. Isi Dapurnya: Apps Script Jadi API
  • 3. Frontend dan Dua Worker
  • 4. Sempat Mentok: Error 405
  • 5. Sempat Bingung: Route /api yang 404
  • 6. Pasang Domain Sendiri
  • 7. Aturan Main Sistemnya
  • 8. Hal yang Saya Pelajari
  • 9. Penutup

1. Gambaran Alurnya Dulu

Sistem ini saya pecah jadi dua bagian. Bagian depan adalah halaman web yang dibuka orang. Bagian belakang adalah Apps Script yang mengurus data ke Google Sheets dan Google Drive.

Kenapa dipecah? Karena kalau halaman ikut menumpang di Apps Script, alamatnya ikut alamat Apps Script. Kalau halamannya dipisah dan ditaruh di tempat lain, alamatnya bisa pakai domain sendiri, sementara Apps Script cukup bekerja di belakang layar.

Arsitektur Sistem

Alurnya kalau ditulis pakai panah kira-kira begini:

Mahasiswa / Admin
↓ buka halaman
Frontend (domain sendiri)
↓ kirim data JSON
API Worker (proxy)
↓ teruskan permintaan
Apps Script Web App (/exec)
↓ baca / tulis
Google Sheets (database) + Google Drive (dokumen)

Halaman mahasiswanya dipakai untuk daftar antrean, cek status antrean, dan unggah dokumen. Halaman adminnya terpisah, masuknya pakai PIN, dipakai untuk memanggil antrean berikutnya, menandai selesai, mengatur jadwal, dan memeriksa dokumen yang masuk.

Alur Daftar Antrian

2. Isi Dapurnya: Apps Script Jadi API

Di Apps Script, fungsi doPost saya jadikan pintu masuk. Setiap permintaan datang membawa satu keterangan: mau melakukan apa. Di kode, keterangan itu dibaca dari isian bernama action.

Bentuk sederhananya begini:

function doPost(e) {
  var data = JSON.parse(e.postData.contents);
  var aksi = data.action;

  if (aksi === "daftar") { return daftarAntrean(data); }
  if (aksi === "cek")    { return cekAntrean(data); }
  if (aksi === "upload_dokumen") { return uploadDokumen(data); }
  if (aksi === "admin_next")     { return panggilBerikutnya(data); }

  return balasJson({ ok: false, pesan: "Action tidak dikenal" });
}

Action yang akhirnya kepakai cukup banyak. Untuk mahasiswa ada daftar, cek, upload_dokumen, dan cek_dokumen. Untuk admin ada admin_list, admin_next, admin_selesai, admin_set_jadwal, admin_list_dokumen, dan admin_update_dokumen.

Contoh permintaan cek antrean dari halaman depan bentuknya begini:

{
  "action": "cek",
  "nim": "0000000000"
}

Dan jawaban dari belakang kira-kira begini. Ini contoh dummy, bukan data asli:

{
  "ok": true,
  "pesan": "Data antrean ditemukan",
  "antrean": {
    "nomor": 7,
    "status": "menunggu"
  }
}

Databasenya bukan database beneran, melainkan Google Sheets. Isinya saya bagi jadi beberapa sheet:

ANTRIAN Isi daftar antrean: nama, NIM, waktu daftar, status.
DOKUMEN Catatan dokumen yang diunggah, file aslinya disimpan di Google Drive.
SETTING Pengaturan, termasuk PIN admin. PIN tersimpan di sheet SETTING, jangan tampilkan PIN asli di tulisan mana pun.
ADMIN dan TOKEN Pendukung untuk keperluan admin dan sesi.

Saat deploy Web App, pengaturannya saya isi: Execute as: Me dan Who has access: Anyone. Alasannya supaya mahasiswa bisa memakai halaman tanpa harus login akun Google dulu. Urusan admin tetap dijaga PIN, bukan dibuka begitu saja.

3. Frontend dan Dua Worker

Halaman depannya saya simpan di repo GitHub yang saya privat, lalu dihubungkan ke Cloudflare. Di Cloudflare, proyek ini jalan sebagai Worker, bukan sekadar tempat menaruh file.

Ada dua Worker yang bekerja:

  • Worker frontend — yang melayani halaman mahasiswa dan halaman admin saat domain dibuka.
  • Worker API — yang jadi perantara antara halaman dan Apps Script.

Kenapa perlu perantara segala? Karena halaman yang jalan di domain sendiri tidak bisa sembarangan memanggil alamat lain, ada aturan keamanan browser yang namanya CORS. Worker API ini yang menjembatani, sekaligus menyembunyikan alamat asli Apps Script dari tampilan luar.

Alamat Apps Script-nya sendiri di kode cukup ditulis seperti ini. Ini contoh yang sudah saya samarkan:

const GAS_URL = "https://script.google.com/macros/s/XXXX-contoh-xxxx/exec";

4. Sempat Mentok: Error 405

Bagian ini yang paling lama bikin saya berhenti. Halaman sudah jadi, Worker sudah jalan, tapi setiap mengirim data balasannya 405.

Setelah diurut pelan-pelan, ternyata masalahnya ada di cara Worker meneruskan kiriman ke Google. Apps Script itu kalau menerima POST, dia tidak langsung menjawab. Dia membalas dengan pengalihan, istilahnya redirect 302, ke alamat sementara.

Kesalahan saya waktu itu: Worker saya ikut-ikutan mengirim POST lagi ke alamat pengalihan itu. Di situlah Google menolak, keluarlah 405.

Solusinya ternyata sepele, tapi tidak kepikiran di awal:

POST cukup sekali saja ke alamat /exec. Setelah itu ikuti pengalihannya pakai GET, karena tiket pengalihan itu sudah membawa data POST yang kita kirim.

Potongan kodenya kira-kira begini:

async function fetchViaGas(body) {
  // 1. POST sekali saja ke /exec, jangan auto mengikuti redirect
  let res = await fetch(GAS_URL, {
    method: "POST",
    body: body,
    redirect: "manual"
  });

  // 2. Kalau dibalas redirect 302, ikuti pakai GET
  let lokasi = res.headers.get("Location");
  if (lokasi) {
    res = await fetch(lokasi, { method: "GET" });
  }

  return res;
}

Setelah bagian itu diperbaiki, kiriman cek antrean langsung dibalas 200 dengan jawaban JSON yang benar. Rasanya lega sekali, karena masalahnya bukan di Apps Script-nya, melainkan di cara meneruskannya.

5. Sempat Bingung: Route /api yang 404

Kejadian kedua tidak kalah aneh. Rencananya halaman dan API mau saya jadikan satu domain, jadi API saya pasang di route /api/* pada domain yang sama.

Dari hasil tes di luar, route itu menjawab 200 dan isinya benar. Tapi dari browser saya sendiri, yang muncul justru 404. Sudah dicoba pakai mode penyamaran, tetap sama.

Di titik itu saya berhenti memaksakan diri. Daripada sistemnya tidak jalan cuma gara-gara satu route, saya pakai jalan keluar yang lebih praktis: di kode halaman depan, alamat API-nya saya isi lengkap memakai alamat bawaan Worker API.

const CONFIG = {
  apiBase: "https://nama-api.username.workers.dev"
};

Kenapa ini aman dipakai? Dua hal. Pertama, Worker API saya beri header CORS yang membuka akses. Kedua, kiriman dari halaman saya buat memakai content type text/plain, jadi browser tidak ribet dengan pemeriksaan awal yang biasanya bikin gagal.

const headers = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type",
  "Content-Type": "application/json"
};

Sampai sekarang route satu domain itu belum saya sentuh lagi. Sistemnya sudah jalan dengan cara ini, jadi saya catat saja sebagai utang lama. Kalau nanti ada waktu dan kepala sedang dingin, baru saya tengok lagi.

6. Pasang Domain Sendiri

Domain yang saya pakai memang sudah saya tambahkan ke Cloudflare sejak awal, jadi urusan nama server tidak perlu diulang dari nol.

Langkah pasang alamatnya begini. Pertama, buka Worker frontend di dashboard Cloudflare. Kedua, masuk ke pengaturan domain dan route. Ketiga, tambahkan Custom Domain dengan subdomain yang diinginkan, contohnya bimbingan.contohdomain.my.id. Keempat, API-nya sekalian diatur jalurnya, dari pengaturan Worker API.

Setelah itu tinggal ditunggu sebentar sampai HTTPS-nya siap, lalu dicoba dibuka seperti membuka website biasa. Momen pertama kali alamat pendek itu kebuka dan halamannya muncul, itu yang bikin semua utak-atik sebelumnya terasa terbayar.

7. Aturan Main Sistemnya

Biar tidak cuma soal teknis, sekalian saya catat aturan main yang saya pasang di sistem ini:

  • Pendaftaran dibuka pukul 08.00 sampai 23.00, di luar itu formulir ditutup.
  • Satu mahasiswa hanya boleh konsultasi satu kali dalam satu minggu.
  • Antrean bisa dibuka atau ditutup dari pengaturan.
  • Dokumen yang diunggah masuk ke folder Drive yang berbeda sesuai jenis dokumennya.
  • Halaman admin hanya bisa dipakai setelah memasukkan PIN, dan PIN-nya tersimpan di sheet SETTING.

8. Hal yang Saya Pelajari

  • Alamat bawaan layanan itu tidak wajib jadi alamat yang dilihat orang. Halaman dan mesin di belakangnya bisa dipisah.
  • Redirect itu bukan error. Dalam kasus Apps Script, redirect 302 justru bagian dari alur normalnya, hanya cara mengikutinya harus benar: POST sekali, lalu GET.
  • Kalau satu jalan mentok terlalu lama, jalan keluar yang sederhana dan terbukti jalan itu lebih berharga daripada memaksakan cara yang paling rapi di atas kertas.
  • Mencatat pesan error dan langkah terakhir sebelum error itu jauh lebih membantu daripada sekadar mengingat "tadi gagal".
  • Sistem kecil seperti ini ternyata tetap butuh aturan main yang jelas, bukan cuma halaman dan tombol.

9. Penutup

Sekarang sistem antrean ini sudah bisa dibuka dari alamat sendiri yang pendek. Mahasiswa tidak perlu lagi menerima link panjang dari saya, dan saya tidak perlu lagi mencari-cari link itu tiap mau membagikan.

Semoga catatan ini bermanfaat, terutama buat saya sendiri kalau nanti lupa dan harus mengulang hal yang sama dari awal.


Disclaimer

Tulisan ini adalah catatan belajar pribadi tentang sistem antrean konsultasi dan domain sendiri, bukan tutorial resmi dan bukan panduan baku dari pihak mana pun. Saya menulis ulang pengalaman saya supaya tidak lupa, bukan karena saya sudah paham.

Prosesnya sendiri banyak dibantu AI dan diskusi bolak-balik, apalagi saat mengatasi error 405 dan route yang 404 itu. Jadi jangan dibayangkan saya sudah paham semuanya. Saya masih belajar, dan sangat mungkin ada bagian di catatan ini yang kurang tepat atau bisa diperbaiki dengan cara yang lebih baik.

Kalau ada yang membaca dan menemukan cara yang lebih rapi, saya justru senang. Yang penting bagi saya, langkahnya tercatat dan bisa dibaca lagi saat lupa, dan semoga bermanfaat juga buat yang sedang belajar hal yang sama.

author

Dwi Yanto

Sebuah Catatan Kecil Hidup Inyonk


Tulis yang dikerjakan, Kerjakan apa yang ditulis

Dapatkan Update Gratis disini!

Posting Komentar

www.CodeNirvana.in

Online Sejak 2013 Dwi Yanto | Blogger Templates | Designed By Code Nirvana