Flujo de verificación de huéspedes
Esta guía explica cómo usar la lista de huéspedes alojados en un portal cautivo: cómo comparar lo que escribe el huésped con la lista, cuándo debe terminar la sesión de Wi-Fi, cada cuánto actualizar la lista y qué campos conservar para los registros de la Ley turca n.º 5651.
Qué pedir en el portal#
Como la lista proporciona a la vez los datos de la habitación y de identidad, el formulario más habitual es número de habitación + apellido. El número de habitación por sí solo no basta: cualquiera que conozca el número de una habitación vecina podría conectarse. Las alternativas son número de habitación + número de identidad o de pasaporte o apellido + fecha de nacimiento; reserva esta última como alternativa para los huéspedes sin número de identidad.
Reglas de coincidencia#
Normaliza ambos lados antes de comparar lo que escribió el huésped con los valores de la lista:
- Número de habitación: elimina los espacios de los extremos y pásalo a mayúsculas.
roomNamees una cadena (puede ser"104","A-12"o"Villa 3"); no la conviertas a número ni elimines los ceros iniciales. - Apellido: pásalo a mayúsculas (ten en cuenta la correspondencia turca
i → İ) y reduce los espacios repetidos a uno. Los valores de la lista suelen leerse del documento de identidad, en mayúsculas. - Número de identidad: quita los espacios y pásalo a mayúsculas. Un número de identidad nacional turco tiene 11 dígitos; un número de pasaporte combina letras y dígitos.
- Fecha de nacimiento: la lista la da en formato
DD.MM.YYYY; conviértela si tu formulario usa otro formato.
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) {
// "El número de habitación y el apellido no coinciden" — cuenta los intentos fallidos y limita tras 5
}El valor unique del registro coincidente es la identidad del usuario del hotspot. Cuando el mismo huésped se conecte desde un segundo dispositivo, reutiliza la cuenta vinculada a este valor en lugar de crear una nueva y aplica a esa cuenta el límite de dispositivos.
Duración de la sesión#
checkout es la fecha de salida prevista y apunta a las 00:00 (UTC) de ese día; no incluye la hora. Si abres la sesión hasta ese momento, el huésped pierde el acceso la mañana de su salida. Calcula el fin de la sesión sumando a la fecha la hora de check-out del hotel:
const CHECKOUT_TIME = "12:00"; // hora de check-out del hotel
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`);Si el huésped se va antes de la hora de check-out, desaparece de la lista; cierra la cuenta en la siguiente sincronización. Si se prolonga la estancia, checkout cambia; compara este campo durante la sincronización y actualiza el fin de la sesión. En las salidas tardías, lo más seguro es mantener el acceso abierto mientras el huésped siga en la lista.
Sincronización periódica#
La lista es una instantánea; no hay notificaciones de cambios (webhooks). Obtén la lista a intervalos fijos y compárala con la anterior por unique:
- Intervalo: 5 minutos bastan para la mayoría de los hoteles. Si se espera que los huéspedes se conecten nada más hacer el check-in, puedes bajar a 1–2 minutos; no bajes de 1 minuto.
uniquenuevo: prepara la cuenta; la coincidencia con el huésped se hace en su primer acceso al portal.uniqueque ya no aparece: el huésped ha hecho el check-out o la reserva se ha cancelado. Termina la sesión y cierra la cuenta.- Mismo
unique, conroomNameocheckoutdistintos: un cambio de habitación o una prolongación de la estancia. Actualiza la cuenta. - Solicitud fallida: ante un tiempo de espera agotado, un
401o un5xx, conserva la última lista obtenida correctamente; nunca cierres cuentas a partir de una respuesta de error.
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: conserva la lista anterior
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); // check-out hecho
}
for (const [id, g] of next) {
const old = prev.get(id);
if (!old) await openAccount(g); // huésped nuevo
else if (old.checkout !== g.checkout || old.roomName !== g.roomName) await updateAccount(g);
}
return next;
}Varios huéspedes en una habitación#
Cada huésped de una habitación es un registro independiente: rezervasyon_id es común y unique es distinto. Abre las cuentas por huésped y no por habitación, para que cada huésped tenga su propio dispositivo, su sesión y su registro de la Ley turca n.º 5651. Una consulta de número de habitación + apellido puede devolver más de un registro si hay huéspedes con el mismo apellido (una familia); en lugar de quedarte con la primera coincidencia, distingue por nombre o por fecha de nacimiento, o abre una cuenta compartida para ellos.
Registros de la Ley turca n.º 5651#
La obligación de conservar los registros de acceso conforme a la Ley turca n.º 5651 recae en el sistema de hotspot; HMS solo proporciona los datos de identidad. Al abrir una sesión, guarda los campos siguientes junto con la dirección MAC/IP y la marca de tiempo: unique, rezervasyon_id, firstName, lastName, identityNumber, birthDate, roomName, checkin, checkout. Cuando un huésped desaparece de la lista, HMS deja de proporcionar esta información; conserva el registro en tu sistema.