Процес на проверка на гостите
Това ръководство обяснява как да използвате списъка с настанените гости в captive портал: съпоставяне на въведеното от госта със списъка, кога трябва да приключи 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 се променя; сравнявайте това поле при синхронизацията и обновявайте края на сесията. При късно напускане е по-сигурно достъпът да остане отворен, докато гостът е в списъка.
Периодична синхронизация#
Списъкът е моментна снимка; няма известяване за промени (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 вече не предоставя тази информация; пазете записа от ваша страна.