Membuat Event Attendance Participant Pakai QRcode Dengan Google Apps Script Tanpa Hosting dan Modal Sedikitpun

event attendance free google apps script

Membuat Event Attendance Participant Pakai QRcode Dengan Google Script Tanpa Hosting dan Modal Sedikitpun

Saat ini banyak orang mencari cara membuat absensi online dengan QR Code tanpa harus mengeluarkan biaya hosting. Google Apps Script adalah solusi tepat untuk sistem kehadiran event attendance gratis yang bisa digunakan pada seminar, workshop, hingga acara kampus. Dengan sedikit langkah sederhana, Anda bisa membuat sistem attendance participant berbasis QR Code tanpa modal besar dan dapat langsung berjalan di Google Spreadsheet. Anda bisa juga bisa membaca absensi menggunakan face capture 

Kenapa Harus Pakai QR Code untuk Absensi?

QR Code mempermudah peserta untuk melakukan check-in atau check-out hanya dengan sekali scan. Dibanding absensi manual dengan tanda tangan, sistem ini lebih cepat, akurat, dan meminimalkan antrian panjang di pintu masuk acara. Selain itu, semua data peserta langsung masuk ke Google Sheets sehingga bisa dipantau secara real time.

Kelebihan Menggunakan Google Apps Script

  • Gratis 100% tanpa biaya hosting
  • Terintegrasi langsung dengan Google Sheets
  • Mudah dibagikan ke panitia dan tim
  • Dapat diakses via browser maupun smartphone

Langkah Membuat Event Attendance dengan QR Code

  1. Buka Google Apps Script dari akun Google Anda.
  2. Buat project baru dan hubungkan dengan Google Spreadsheet untuk menyimpan data peserta.
  3. Tulis kode sederhana untuk form check-in berdasarkan kode unik peserta.
  4. Generate QR Code untuk tiap peserta (bisa menggunakan API gratis seperti Google Chart QR API).
  5. Bagikan QR Code ke email peserta atau cetak di tiket acara.
  6. Sediakan halaman scan QR via smartphone panitia atau peserta untuk check-in otomatis.

Struktur Data di Google Spreadsheet

Sheet Participant

Anda bisa membuat kolom participant seperti berikut:

  • KodeBooking
  • Nama
  • Event
  • Room
  • Pembayaran(paid/unpaid)

Sheet Attendance

Anda bisa membuat kolom attendance seperti berikut:

  • KodeBooking
  • Nama
  • Event
  • Room
  • Type (Check-in / Check-out)
  • Waktu

Cara Generate QR Code

Untuk membuat QR Code unik, Anda bisa gunakan link seperti:

https://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=KODEPESERTA123
  

Setiap peserta akan memiliki QR Code berbeda berdasarkan kode booking event unik yang Anda buat. Saat discan, QR Code tersebut akan diarahkan ke Google Apps Script Web App untuk memproses absensi.

$ads={1}

Penerapan di Lapangan

Sistem absensi QR Code ini sudah banyak dipakai di acara kampus, seminar, hingga pelatihan online. Cukup dengan scan, data kehadiran langsung tersimpan otomatis. Hasil laporan dapat diekspor ke Excel atau Google Data Studio untuk visualisasi kehadiran.

Kode Google Apps Script

Berikut kode yang digunakan terdiri dari 4 file seperti code.gs, index.html, admin.html, dan laporan.html. Untuk scriptnya sebagai berikut.

Script code.gs

var SHEET_ID = "xxxxxxxxxxxx"; // ganti dengan ID Sheet Anda

function doGet(e) {
  var page = e.parameter.page || "Index";
  return HtmlService.createHtmlOutputFromFile(page)
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

// ==== ABSENSI (scan) ====
function checkInParticipant(kode, type) {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var participantSheet = ss.getSheetByName("participant");
  var attendanceSheet = ss.getSheetByName("attendance");

  var data = participantSheet.getDataRange().getValues();
  var found = null;
  for (var i = 1; i < data.length; i++) {
    if (data[i][0] == kode) {
      found = {
        kodebooking: data[i][0],
        nama: data[i][1],
        event: data[i][2],
        room: data[i][3]
      };
      break;
    }
  }

  if (!found) {
    return "❌ Peserta tidak ditemukan!";
  }

  attendanceSheet.appendRow([
    found.kodebooking,
    found.nama,
    found.event,
    found.room,
    type,
    new Date()
  ]);

  return "✅ " + found.nama + " berhasil " + type;
}

// ==== ADMIN PESERTA ====
function getParticipants() {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sheet = ss.getSheetByName("participant");
  var data = sheet.getDataRange().getValues();
  data.shift(); // hapus header
  return data;
}

function addParticipant(kode, nama, event, room) {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sheet = ss.getSheetByName("participant");
  sheet.appendRow([kode, nama, event, room]);
  return "Peserta ditambahkan.";
}

function updateParticipant(row, kode, nama, event, room) {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sheet = ss.getSheetByName("participant");
  sheet.getRange(row, 1, 1, 4).setValues([[kode, nama, event, room]]);
  return "Peserta diperbarui.";
}

function deleteParticipant(row) {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sheet = ss.getSheetByName("participant");
  sheet.deleteRow(row);
  return "Peserta dihapus.";
}

// ==== LAPORAN ABSENSI ====
function getAttendance() {
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sh = ss.getSheetByName("attendance");
  if (!sh) {
    Logger.log("❌ Sheet 'attendance' tidak ditemukan");
    return [];
  }

  var data = sh.getDataRange().getValues();
  Logger.log("Raw data: " + JSON.stringify(data));

  if (data.length <= 1) {
    Logger.log("⚠️ Tidak ada data (hanya header)");
    return [];
  }

  var headers = data.shift();
  var result = data.map(function(row) {
    return {
      kode: row[0] ? String(row[0]) : "",
      nama: row[1] || "",
      event: row[2] || "",
      room: row[3] ? row[3].toString().trim() : "",
      type: row[4] || "",
      waktu: row[5] ? row[5].toString() : ""
    };
  });

  Logger.log(result);
  return JSON.parse(JSON.stringify(result));
}

function testAttendance(){
  return getAttendance();
}

$ads={2}

Script html


#Index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Absensi Panitia</title>
    <style>
      body { font-family: Arial, sans-serif; padding: 20px; }
      input, select, button { padding: 8px; margin: 5px 0; width: 100%; }
      #reader { width: 100%; margin: 10px auto; }
      #result { margin-top: 15px; font-weight: bold; }
    </style>
    <!-- Library QR Scanner versi stabil -->
    <script src="https://unpkg.com/html5-qrcode@2.3.8/html5-qrcode.min.js"></script>
  </head>
  <body>
    <h2>Form Absensi Event</h2>

    <div id="reader"></div>

    <label>Kode Booking (hasil scan):</label>
    <input type="text" id="kode" placeholder="Kode otomatis dari scan" readonly>

    <label>Tipe Absensi:</label>
    <select id="type">
      <option value="checkin">Check In</option>
      <option value="checkout">Check Out</option>
    </select>

    <button onclick="submitAttendance()">Simpan Absensi</button>

    <div id="result"></div>

<p>Didukung: <a href="https://www.mampirklik.com">www.mampirklik.com</a> || <a href="https://cmsgue.id">cmsgue.id</a></p>
    <script>
      function onScanSuccess(decodedText) {
        document.getElementById("kode").value = decodedText;
      }

      function onScanFailure(error) {
        // opsional: log error
        // console.warn(error);
      }

      // pastikan dijalankan setelah lib loaded
      window.onload = function() {
        let html5QrcodeScanner = new Html5QrcodeScanner(
          "reader",
          { fps: 10, qrbox: { width: 250, height: 250 } },
          false
        );
        html5QrcodeScanner.render(onScanSuccess, onScanFailure);
      };

      function submitAttendance() {
        var kode = document.getElementById("kode").value.trim();
        var type = document.getElementById("type").value;
        if (!kode) {
          document.getElementById("result").innerHTML = "⚠️ Harap scan QR Code peserta.";
          return;
        }
        google.script.run.withSuccessHandler(function(msg) {
          document.getElementById("result").innerHTML = msg;
          document.getElementById("kode").value = "";
        }).checkInParticipant(kode, type);
      }
    </script>
  </body>
</html>

#Admin.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Admin - Peserta</title>
  <style>
    body { font-family: Arial; padding: 20px; }
    table { border-collapse: collapse; width: 100%; margin-top: 10px; }
    th, td { border: 1px solid #ccc; padding: 6px; }
    input { margin: 4px; padding: 6px; }
  </style>
</head>
<body>
  <h2>Daftar Peserta</h2>
  <div>
    <input type="text" id="kode" placeholder="Kode Booking">
    <input type="text" id="nama" placeholder="Nama">
    <input type="text" id="event" placeholder="Event Seminar">
    <input type="text" id="room" placeholder="Room">
    <button onclick="add()">Tambah Peserta</button>
  </div>
  <div id="msg"></div>
  <table id="tbl">
    <thead>
      <tr><th>Kode</th><th>Nama</th><th>Event</th><th>Room</th><th>Aksi</th></tr>
    </thead>
    <tbody></tbody>
  </table>

<script>
  function loadData() {
    google.script.run.withSuccessHandler(function(data){
      var tbody = document.querySelector("#tbl tbody");
      tbody.innerHTML = "";
      data.forEach(function(row, i){
        var tr = document.createElement("tr");
        tr.innerHTML = `
          <td><input value="${row[0]}"></td>
          <td><input value="${row[1]}"></td>
          <td><input value="${row[2]}"></td>
          <td><input value="${row[3]}"></td>
          <td>
            <button onclick="update(${i+2}, this)">Update</button>
            <button onclick="hapus(${i+2})">Hapus</button>
          </td>
        `;
        tbody.appendChild(tr);
      });
    }).getParticipants();
  }

  function add() {
    var kode=document.getElementById("kode").value;
    var nama=document.getElementById("nama").value;
    var event=document.getElementById("event").value;
    var room=document.getElementById("room").value;
    google.script.run.withSuccessHandler(function(msg){
      document.getElementById("msg").innerHTML=msg;
      loadData();
    }).addParticipant(kode,nama,event,room);
  }

  function update(row, el) {
    var tr = el.parentNode.parentNode;
    var kode = tr.cells[0].children[0].value;
    var nama = tr.cells[1].children[0].value;
    var event = tr.cells[2].children[0].value;
    var room = tr.cells[3].children[0].value;
    google.script.run.withSuccessHandler(function(msg){
      document.getElementById("msg").innerHTML=msg;
      loadData();
    }).updateParticipant(row,kode,nama,event,room);
  }

  function hapus(row) {
    if(confirm("Yakin hapus peserta?")){
      google.script.run.withSuccessHandler(function(msg){
        document.getElementById("msg").innerHTML=msg;
        loadData();
      }).deleteParticipant(row);
    }
  }

  loadData();
</script>
</body>
</html>

#Laporan.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Laporan Absensi</title>
  <style>
    body { font-family: Arial; padding: 20px; }
    table { border-collapse: collapse; width: 100%; margin-top: 10px; }
    th, td { border: 1px solid #ccc; padding: 6px; }
  </style>
</head>
<body>
  <h2>Laporan Absensi</h2>
  <label>Filter Room:</label>
  <input type="text" id="filterRoom" onkeyup="loadData()">
  <table id="tbl">
    <thead>
      <tr><th>Kode</th><th>Nama</th><th>Event</th><th>Room</th><th>Tipe</th><th>Waktu</th></tr>
    </thead>
    <tbody></tbody>
  </table>

<script>
    function loadData() {
      var filterRoom = document.getElementById("filterRoom").value.toLowerCase().trim();

      google.script.run.withSuccessHandler(function(data){
        var tbody=document.querySelector("#tbl tbody");
        tbody.innerHTML="";

        if (!Array.isArray(data) || data.length === 0) {
          tbody.innerHTML = "<tr><td colspan='6'>⚠️ Belum ada data absensi</td></tr>";
          return;
        }

        data.forEach(function(row){
          var room = (row.room || "").toLowerCase().trim();

          if(filterRoom === "" || room.includes(filterRoom)){
            var tr=document.createElement("tr");
            tr.innerHTML = `
              <td>${row.kode || ""}</td>
              <td>${row.nama || ""}</td>
              <td>${row.event || ""}</td>
              <td>${row.room || ""}</td>
              <td>${row.type || ""}</td>
              <td>${row.waktu || ""}</td>`;
            tbody.appendChild(tr);
          }
        });
      }).getAttendance();
    }

    // load awal
    loadData();
</script>
</body>
</html>

Dengan Google Apps Script, Anda bisa membuat sistem event attendance participant pakai QR Code tanpa hosting, tanpa modal, dan langsung terintegrasi dengan Google Spreadsheet. Solusi ini sangat cocok untuk panitia acara yang ingin efisien, hemat biaya, serta mudah digunakan oleh peserta maupun penyelenggara.

Cara Akses Halaman

Akses halaman secara default pada Index.html dan untuk akses masing - masing seperti Admin.html dan Laporan.html cukup gunakan ?page=Admin atau ?page=Laporan pada akhir url deploy Google Apps Script

Untuk tutorial lebih detail, Anda bisa membaca panduan resmi di Google Apps Script Documentation. Jika ada kesulitan bisa chat di facebook atau komentar pada video youtube saya.

Posting Komentar

Lebih baru Lebih lama

نموذج الاتصال