ردیابی زنده بازدیدکنندگان وب‌سایت بدون نیاز به اشتراک

یکی از مشتریان می‌خواست بداند چه کسانی در لحظه در وب‌سایت او حضور دارند.

آن‌ها ویجت Tidio را دوست داشتند اما نمی‌خواستند هزینه‌ی اشتراک را پرداخت کنند.

چالش شامل دو بخش بود:

  • سایت از وردپرس روی هاستینگ‌های مختلف استفاده می‌کرد.
  • نمی‌توانستم Firebase را مستقیماً به تنظیمات وردپرس اضافه کنم.

من یک ردیاب خارجی با استفاده از Firebase ساختم. روش کار به این صورت است:

راهکار

من از یک تگ script واحد در هدر وردپرس استفاده کردم. این اسکریپت به یک پروژه مستقل Firebase متصل می‌شود.

• حضور زنده: من از Firebase Realtime Database به همراه تابع onDisconnect() استفاده کردم. این تابع وقتی کاربر تب خود را می‌بندد یا اتصالش قطع می‌شود، او را به‌طور خودکار از لیست «آنلاین» حذف می‌کند. • تاریخچه بازدیدکنندگان: من از یک Netlify Function برای نوشتن داده‌ها در Firestore استفاده کردم. این کار امکان تعیین موقعیت جغرافیایی (geolocation) بر اساس IP را در سمت سرور فراهم می‌کند. • امنیت: من از احراز هویت ناشناس (anonymous authentication) استفاده کردم. بازدیدکنندگان فقط می‌توانند در گره (node) مربوط به نشست (session) خود بنویسند. فقط مدیر (admin) می‌تواند لیست کامل را بخواند.

باگ‌های چالش‌برانگیز

ساخت این سیستم بدون مشکل نبود. من با سه مانع فنی بزرگ روبرو شدم.

۱. تله‌ی کش (Caching) تاریخچه، صفر نشست را نشان می‌داد. متوجه شدم که اسکریپت ردیاب دارای سیاست کش یک‌ساله است. بازدیدکنندگان درگیر استفاده از نسخه قدیمی اسکریپت بودند.

  • راهکار: من یک سیاست کش پنج دقیقه‌ای برای اسکریپت ردیاب تنظیم کردم.

۲. خطای کاذب CORS مرورگر خطای CORS گزارش می‌کرد. فکر کردم مشکل از لیست سفید دامنه (domain whitelist) است. یک تست ساده با curl نشان داد که سرور به‌درستی کار می‌کند. واقعیت متفاوت بود. سرور در واقع در حال کرش کردن (crash) بود. در Node.js، اگر از کد وضعیت (status code) 204 استفاده کنید، نمی‌توانید از یک رشته خالی به عنوان بدنه (body) استفاده کنید. باید از null استفاده کنید. رشته خالی باعث کرش کردن سرور قبل از ارسال هدرهای CORS می‌شد. مرورگر هیچ هدرهایی دریافت نمی‌کرد و تصور می‌کرد مشکل از CORS است.

  • راهکار: بدنه پاسخ را از '' به null تغییر دادم.

۳. شکاف داده‌های مفقود شده فیلترهای «امروز» یا «۷ روز گذشته» هیچ نتیجه‌ای بر نمی‌گرداندند. موقعیت برخی کاربران «نامشخص» (Unknown) نمایش داده می‌شد. این اتفاق به این دلیل رخ داد که من برچسب زمانی (timestamp) و موقعیت مکانی را فقط در اولین بارگذاری صفحه محاسبه می‌کردم. اگر کاربری یک نشست قدیمی در مرورگر خود داشت، سرور رویداد «شروع» (start) را از دست می‌داد.

  • راهکار: من محاسبات را به صورت هم‌ریخت (idempotent) انجام دادم. اکنون اسکریپت این مقادیر را در هر رویداد دوباره محاسبه می‌کند.

نکات کلیدی

• خطای CORS در مرورگر همیشه یک مشکل پیکربندی نیست؛ بلکه می‌تواند نشانه‌ی کرش کردن سرور باشد. همیشه لاگ‌های سرور خود را بررسی کنید. • تست curl POST رفتار مرورگر را شبیه‌سازی نمی‌کند. مرورگرها ابتدا یک درخواست OPTIONS preflight ارسال می‌کنند. تست شما برای معتبر بودن باید شامل این مورد باشد. • برای وضعیت‌های HTTP که «بدون محتوا» هستند (مانند 204)، از null استفاده کنید. از رشته‌های خالی استفاده نکنید.

منبع: https://dev.to/androve2k/whos-online-on-the-site-without-tidio-live-presence-and-visitor-history-with-firebase-37il