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. roomName es 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.
Coincidencia
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:

Fin de la sesión
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.
  • unique nuevo: prepara la cuenta; la coincidencia con el huésped se hace en su primer acceso al portal.
  • unique que 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, con roomName o checkout distintos: un cambio de habitación o una prolongación de la estancia. Actualiza la cuenta.
  • Solicitud fallida: ante un tiempo de espera agotado, un 401 o un 5xx, conserva la última lista obtenida correctamente; nunca cierres cuentas a partir de una respuesta de error.
Bucle de sincronización
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.

Última actualización: 21 de septiembre de 2026¿Has encontrado un error? Avísanos