✅ การทำงาน
- 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>