Google Apps Script เปิด-ปิด หน้าเว็บ ด้วยเวลาทีฝั่ง Server

 

✅ การทำงาน

  • Server (GAS) เช็คเวลาปัจจุบัน ถ้าอยู่นอกช่วง → แสดง closed.html ทันที
  • ถ้าอยู่ในช่วงเวลา → ส่ง index.html พร้อมฝัง closeTime (เวลาปิดของวันนั้น)
  • Client ใช้ setInterval อัปเดต นับถอยหลัง ทุกวินาที
  • เมื่อถึงเวลา → แสดง “หมดเวลาบริการ” และ reload หน้า → Server จะส่ง closed.html

โค้ดเช็คเวลาที่ฝั่ง Server (Google Apps Script) มี ข้อดี และ ข้อจำกัด อย่างไร

✅ ข้อดี

1. ควบคุมได้จริง

  • ผู้ใช้จะไม่สามารถแก้เวลาในเครื่อง (client) เพื่อหลอกระบบได้
  • เพราะการตรวจสอบเวลาเกิดที่ Server ของ Google ไม่ใช่ที่ browser

2. ป้องกันการเข้าถึงจริง ๆ

  • ถ้าอยู่นอกเวลา ระบบจะ ไม่ส่งหน้า index.html กลับมาเลย
  • ต่อให้ปิด JavaScript หรือแก้ HTML ฝั่ง client ก็เข้าไม่ได้

3. ปลอดภัยกว่า client-side

  • Logic อยู่บน Server → ผู้ใช้มองไม่เห็น source code ส่วนนี้
  • ลดความเสี่ยงในการถูก bypass

4. รองรับหลายผู้ใช้พร้อมกัน

  • ทุก request จะถูกตรวจสอบเวลาแบบเดียวกัน
  • ไม่ต้องกลัวว่าแต่ละเครื่อง client เวลาไม่ตรงกัน

5. ยืดหยุ่น

  • ปรับช่วงเวลา เปิด–ปิด หรือเพิ่มรอบเวลา (เช้า/บ่าย/พักกลางวัน) ได้ง่าย
  • ข้อมูลเวลาอาจเก็บใน Google Sheet แล้วให้ server ดึงมาใช้ก็ได้


⚠️ ข้อจำกัด

1. พึ่งพา Timezone ของ Server (Google)

  • Google Apps Script รันอยู่ที่โซนเวลาของโปรเจ็กต์ (ค่าเริ่มต้น UTC หรือ GMT+0)
  • ต้องตั้งค่า Script Timezone (ใน Project Settings) ให้ตรงกับเขตเวลาที่ใช้งาน (เช่น GMT+7 สำหรับไทย) ไม่งั้นเวลาเพี้ยน


2. ไม่เหมาะกับการอัปเดตแบบ real-time

  • ถ้าผู้ใช้เปิดเว็บอยู่แล้วถึงเวลา “ปิด” ระบบจะยังไม่บังคับปิดจนกว่าจะ reload หรือมีการ request ใหม่
  • ต้องเขียน JS ฝั่ง client ช่วย refresh/check เพิ่ม ถ้าอยากให้ออกจากระบบอัตโนมัต

3. ประสิทธิภาพ

  • ทุก request จะต้องผ่าน server → อาจช้ากว่า client-side ที่เช็คเองทันที

4. ไม่ยืดหยุ่นเท่าฝั่ง client ใน UI

  • UI แบบ “นับถอยหลังปิด”, “บอกเวลาเปิดครั้งถัดไป” ต้องให้ client คำนวณเพิ่ม เพราะ server เช็คแค่ตอน request

5. ไม่สามารถแก้ปัญหา network delay

  • ถ้า user request ตอน 16:59:59 แต่ server ประมวลผลเสร็จตอน 17:00:01 → อาจโดนตัดว่า “ปิดแล้ว”


👉 สรุป

  • Server-side (GAS) = ใช้ควบคุมจริง ปลอดภัย เชื่อถือได้
  • Client-side (JS) = ใช้ตกแต่ง UI/แจ้งเตือน แต่ไม่ปลอดภัย


Code.gs

     
function doGet(e) {
  // === ตั้งค่าเวลาบริการทุกวัน ===
  const OPEN_HOUR = 9;   // เปิด 09:00
  const CLOSE_HOUR = 17; // ปิด 17:00

  // เวลาปัจจุบัน
  const now = new Date();
  const currentHour = now.getHours();
  const currentMinute = now.getMinutes();

  const currentTotalMinutes = currentHour * 60 + currentMinute;
  const openTotalMinutes = OPEN_HOUR * 60;
  const closeTotalMinutes = CLOSE_HOUR * 60;

  if (currentTotalMinutes >= openTotalMinutes && currentTotalMinutes < closeTotalMinutes) {
    // คำนวณเวลาปิดเป็น timestamp ส่งไปยัง client
    const todayClose = new Date(now);
    todayClose.setHours(CLOSE_HOUR, 0, 0, 0);

    const template = HtmlService.createTemplateFromFile("index");
    template.closeTime = todayClose.getTime(); // ส่งเวลาแบบ UNIX timestamp
    return template.evaluate()
      .setTitle("ระบบออนไลน์")
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  } else {
    return HtmlService.createHtmlOutputFromFile("closed")
      .setTitle("ปิดให้บริการ")
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  }
}


    


index.html

     
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ระบบออนไลน์</title>
  <style>
    body { font-family: sans-serif; text-align: center; margin-top: 50px; }
    .countdown { font-size: 1.5em; color: #0066cc; margin-top: 20px; }
  </style>
</head>
<body>
  <h1>✅ ระบบเปิดให้บริการ</h1>
  <p>เวลาปิดระบบวันนี้: 17:00</p>
  <div class="countdown">เหลือเวลาอีก: <span id="timer">--:--:--</span></div>

  <script>
    // ===== ดึงค่า closeTime จาก server (แทรกเป็นตัวเลข JS) =====
    const closeTime = new Date(<?= closeTime ?>);

    function updateCountdown() {
      const now = new Date();
      const diff = closeTime - now;

      if (diff <= 0) {
        document.querySelector(".countdown").innerHTML = "⛔ หมดเวลาบริการแล้ว";
        // reload หน้าเพื่อให้ server เช็คอีกครั้ง
        setTimeout(() => location.reload(), 2000);
        return;
      }

      const hours = String(Math.floor(diff / (1000 * 60 * 60))).padStart(2, '0');
      const minutes = String(Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))).padStart(2, '0');
      const seconds = String(Math.floor((diff % (1000 * 60)) / 1000)).padStart(2, '0');

      document.getElementById("timer").textContent = `${hours}:${minutes}:${seconds}`;
    }

    setInterval(updateCountdown, 1000);
    updateCountdown();
  </script>
</body>
</html>


    


closed.html

     
<html>
<head>
  <meta charset="UTF-8">
  <title>ปิดให้บริการ</title>
</head>
<body style="font-family: sans-serif; text-align: center; margin-top: 50px;">
  <h1>⛔ ขณะนี้อยู่นอกเวลาให้บริการ</h1>
  <p>เวลาให้บริการ: 09:00 – 17:00 ทุกวัน</p>
</body>
</html>

    





แสดงความคิดเห็น (0)
ใหม่กว่า เก่ากว่า