مسار التحقق من النزلاء
يشرح هذا الدليل كيفية استخدام قائمة النزلاء المقيمين في بوابة تسجيل الدخول (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؛ فقارن هذا الحقل أثناء المزامنة وحدّث نهاية الجلسة. وفي حالات المغادرة المتأخرة، الأسلم إبقاء الوصول مفتوحًا ما دام النزيل في القائمة.
المزامنة الدورية#
القائمة لقطة للحالة الراهنة، ولا يوجد إشعار بالتغييرات (webhook). اجلب القائمة على فترات ثابتة وقارنها بالقائمة السابقة حسب unique:
- الفاصل الزمني: 5 دقائق تكفي لمعظم الفنادق. وإذا كان يُتوقع أن يتصل النزلاء بالإنترنت فور تسجيل الوصول، فيمكنك النزول إلى 1–2 دقيقة؛ لكن لا تنزل عن دقيقة واحدة.
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 توفّر هذه المعلومات؛ لذا احتفظ بالسجل من جهتك.