ขั้นตอนการตรวจสอบผู้เข้าพัก
คู่มือนี้อธิบายวิธีใช้รายชื่อผู้เข้าพักในโรงแรมกับ captive portal ได้แก่ การจับคู่ข้อมูลที่ผู้เข้าพักกรอกกับรายการ เวลาที่ควรสิ้นสุดเซสชัน Wi-Fi ความถี่ในการรีเฟรชรายการ และฟิลด์ที่ต้องเก็บไว้สำหรับบันทึกตามกฎหมาย 5651
สิ่งที่ควรถามบนพอร์ทัล#
เนื่องจากรายการมีทั้งข้อมูลห้องและข้อมูลระบุตัวตน รูปแบบที่ใช้กันมากที่สุดคือ หมายเลขห้อง + นามสกุล หมายเลขห้องเพียงอย่างเดียวไม่เพียงพอ เพราะใครก็ตามที่รู้หมายเลขห้องข้างเคียงก็เข้าสู่ระบบได้ ทางเลือกอื่นคือ หมายเลขห้อง + หมายเลขบัตรประจำตัว/หนังสือเดินทาง หรือ นามสกุล + วันเกิด โดยให้ใช้แบบหลังเป็นทางสำรองสำหรับผู้เข้าพักที่ไม่มีหมายเลขเอกสารประจำตัว
กฎการจับคู่#
ปรับรูปแบบค่าทั้งสองฝั่งให้เป็นมาตรฐานก่อนเปรียบเทียบข้อมูลที่ผู้เข้าพักกรอกกับค่าในรายการ:
- หมายเลขห้อง: ตัดช่องว่างหัวท้ายและแปลงเป็นตัวพิมพ์ใหญ่
roomNameเป็นสตริง (อาจเป็น"104","A-12"หรือ"Villa 3") อย่าแปลงเป็นตัวเลขหรือตัดเลขศูนย์นำหน้าทิ้ง - นามสกุล: แปลงเป็นตัวพิมพ์ใหญ่ (ระวังการแปลงตัวอักษรภาษาตุรกี
i → İ) และยุบช่องว่างที่ซ้ำกันให้เหลือช่องเดียว ค่าในรายการมักอ่านมาจากเอกสารประจำตัวเป็นตัวพิมพ์ใหญ่ - หมายเลขเอกสารประจำตัว: ลบช่องว่างและแปลงเป็นตัวพิมพ์ใหญ่ เลขประจำตัวประชาชนตุรกีมี 11 หลัก ส่วนหมายเลขหนังสือเดินทางมีทั้งตัวอักษรและตัวเลข
- วันเกิด: รายการให้ค่าในรูปแบบ
DD.MM.YYYYหากแบบฟอร์มของคุณรับรูปแบบอื่น ให้แปลงก่อน
const norm = (s) => String(s ?? "")
.replace(/\s+/g, " ")
.trim()
.toLocaleUpperCase("tr-TR");
function findGuest(list, room, lastName) {
return list.find((g) =>
norm(g.roomName) === norm(room) && norm(g.lastName) === norm(lastName)
) || null;
}
const guest = findGuest(data.otelde, form.room, form.lastName);
if (!guest) {
// "หมายเลขห้องและนามสกุลไม่ตรงกัน" — นับจำนวนครั้งที่ล้มเหลว และจำกัดการลองหลังครบ 5 ครั้ง
}ค่า unique ของรายการที่ตรงกันคือตัวตนของผู้ใช้ Hotspot เมื่อผู้เข้าพักคนเดิมเข้าสู่ระบบจากอุปกรณ์เครื่องที่สอง ให้ใช้บัญชีที่ผูกกับค่านี้ซ้ำแทนการสร้างบัญชีใหม่ และบังคับใช้ขีดจำกัดจำนวนอุปกรณ์กับบัญชีนั้น
อายุเซสชัน#
checkout คือวันเช็กเอาต์ตามแผน และชี้ไปที่เวลา 00:00 (UTC) ของวันนั้นโดยไม่มีข้อมูลเวลา หากคุณเปิดเซสชันไว้ถึงเวลานั้น ผู้เข้าพักจะเสียการเข้าถึงตั้งแต่เช้าวันเดินทางออก ให้คำนวณเวลาสิ้นสุดเซสชันโดยบวกเวลาเช็กเอาต์ของโรงแรมเข้ากับวันที่:
const CHECKOUT_TIME = "12:00"; // เวลาเช็กเอาต์ของโรงแรม
const day = new Date(guest.checkout * 1000)
.toLocaleDateString("en-CA", { timeZone: "UTC" }); // "2026-09-10"
const sessionEnd = new Date(`${day}T${CHECKOUT_TIME}:00+03:00`);หากผู้เข้าพักออกไปก่อนเวลาเช็กเอาต์ ผู้เข้าพักจะหายไปจากรายการ ให้ปิดบัญชีในการซิงค์ครั้งถัดไป หากมีการขยายเวลาเข้าพัก checkout จะเปลี่ยน ให้เปรียบเทียบฟิลด์นี้ระหว่างการซิงค์และอัปเดตเวลาสิ้นสุดเซสชัน สำหรับการเช็กเอาต์ล่าช้า การเปิดการเข้าถึงไว้ตราบที่ผู้เข้าพักยังอยู่ในรายการจะปลอดภัยกว่า
การซิงค์เป็นระยะ#
รายการเป็นภาพข้อมูล ณ ขณะหนึ่ง (snapshot) และไม่มีการแจ้งเตือนการเปลี่ยนแปลง (webhook) ให้ดึงรายการตามช่วงเวลาที่กำหนด แล้วเปรียบเทียบกับรายการก่อนหน้าโดยใช้ unique:
- ช่วงเวลา: 5 นาทีเพียงพอสำหรับโรงแรมส่วนใหญ่ หากต้องการให้ผู้เข้าพักออนไลน์ได้ทันทีที่เช็กอิน สามารถลดลงเหลือ 1–2 นาทีได้ แต่อย่าต่ำกว่า 1 นาที
uniqueใหม่: เตรียมบัญชีไว้ ผู้เข้าพักจะถูกจับคู่เมื่อเข้าสู่ระบบผ่านพอร์ทัลครั้งแรกuniqueที่หายไป: ผู้เข้าพักเช็กเอาต์แล้วหรือการจองถูกยกเลิก ให้สิ้นสุดเซสชันและปิดบัญชีuniqueเดิม แต่roomNameหรือcheckoutต่างไป: มีการย้ายห้องหรือขยายเวลาเข้าพัก ให้อัปเดตบัญชี- คำขอล้มเหลว: เมื่อหมดเวลา ได้รับ
401หรือ5xxให้เก็บรายการล่าสุดที่ดึงสำเร็จไว้ และห้ามปิดบัญชีโดยอิงจากการตอบกลับที่เป็นข้อผิดพลาด
async function sync(prev) {
const res = await fetch(BASE + "/public/json/customer/inhotel", {
method: "POST",
headers: { "ApiKey": process.env.HMS_API_KEY, "HotelCode": HOTEL_CODE }
});
if (!res.ok) return prev; // 401 / 5xx: ใช้รายการเดิมต่อไป
const { success, otelde } = await res.json();
if (success !== 1) return prev;
const next = new Map(otelde.map((g) => [g.unique, g]));
for (const [id] of prev) {
if (!next.has(id)) await closeAccount(id); // เช็กเอาต์แล้ว
}
for (const [id, g] of next) {
const old = prev.get(id);
if (!old) await openAccount(g); // ผู้เข้าพักใหม่
else if (old.checkout !== g.checkout || old.roomName !== g.roomName) await updateAccount(g);
}
return next;
}ผู้เข้าพักหลายคนในห้องเดียว#
ผู้เข้าพักแต่ละคนในห้องเป็นรายการแยกกัน โดย rezervasyon_id เหมือนกัน แต่ unique ต่างกัน ให้เปิดบัญชีแยกตามผู้เข้าพักแทนการเปิดตามห้อง เพื่อให้ผู้เข้าพักแต่ละคนมีอุปกรณ์ เซสชัน และบันทึกตามกฎหมาย 5651 ของตนเอง การค้นหาด้วยหมายเลขห้อง + นามสกุลอาจได้ผลลัพธ์มากกว่าหนึ่งรายการสำหรับผู้เข้าพักที่ใช้นามสกุลเดียวกัน (ครอบครัว) แทนที่จะเลือกรายการแรกที่ตรงกัน ให้แยกแยะด้วยชื่อหรือวันเกิด หรือเปิดบัญชีร่วมให้
บันทึกตามกฎหมาย 5651#
หน้าที่ในการเก็บบันทึกการเข้าใช้งานตามกฎหมายตุรกีฉบับที่ 5651 เป็นของระบบ Hotspot ส่วน HMS เพียงให้ข้อมูลระบุตัวตนเท่านั้น เมื่อเปิดเซสชัน ให้จัดเก็บฟิลด์ต่อไปนี้พร้อมกับที่อยู่ MAC/IP และเวลา: unique, rezervasyon_id, firstName, lastName, identityNumber, birthDate, roomName, checkin, checkout เมื่อผู้เข้าพักหายไปจากรายการ HMS จะไม่ให้ข้อมูลนี้อีก จึงต้องเก็บบันทึกไว้ในฝั่งของคุณ