تخطي إلى المحتوى
Integration

كيفية إضافة الموقع الجغرافي IP إلى SaaS الخاص بك في 20 دقيقة

| 7 min read

أربع ميزات SaaS تحتاج إلى تحديد الموقع الجغرافي عبر IP: الإعدادات الافتراضية للعملة، ولافتات القانون العام لحماية البيانات (GDPR)، واكتشاف الاحتيال، ولوحات المعلومات التحليلية. كود العمل لكل منها، لا حاجة لخرائط جوجل.

World map with location pins showing IP geolocation data
Photo by NASA on Unsplash

يعرض SaaS الخاص بك الدولار الأمريكي لمستخدم في برلين. يظهر شعار ملفات تعريف الارتباط الخاص بك للزوار في ولاية تكساس. لا يمكن لنظام الاحتيال الخاص بك الإبلاغ عندما يستخدم عنوان IP نيجيري عنوان إرسال فواتير ألماني. أربع ميزات تحتاج إلى تحديد الموقع الجغرافي لـ IP، ويمكنك إضافة الأربعة جميعًا في 20 دقيقة باستخدام واجهة برمجة تطبيقات واحدة.

استدعاء API

تبدأ كل ميزة في هذا المنشور بنفس نقطة النهاية. وهنا الضفيرة الخام:

curl -X POST https://api.botoi.com/v1/ip/lookup \\
  -H "Content-Type: application/json" \\
  -d '{"ip": "8.8.8.8"}'

إجابة:

{
  "success": true,
  "data": {
    "ip": "8.8.8.8",
    "city": "Mountain View",
    "region": "California",
    "country": "US",
    "countryName": "United States",
    "latitude": 37.386,
    "longitude": -122.0838,
    "timezone": "America/Los_Angeles",
    "isp": "Google LLC",
    "org": "Google Public DNS",
    "as": "AS15169 Google LLC"
  }
}

يمنحك One POST المدينة والمنطقة ورمز البلد واسم البلد الكامل والإحداثيات والمنطقة الزمنية، رقم مزود خدمة الإنترنت والمؤسسة ورقم AS. هذه بيانات كافية لتشغيل الميزات الأربعة أدناه.

الميزة الأولى: التحديد التلقائي للعملة عند الخروج

يؤدي عرض العملة الخاطئة عند الخروج إلى قتل معدلات التحويل. زائر من ألمانيا يرى "49.99 دولارًا" وعليه أن يتحول عقليًا إلى اليورو قبل اتخاذ القرار. والأسوأ من ذلك أنهم قد يفعلون ذلك افترض أنك لا تخدم منطقتهم.

قم بإصلاح هذه المشكلة باستخدام البرامج الوسيطة التي تقوم بتعيين بلد IP الخاص بالزائر إلى عملة افتراضية:

const COUNTRY_CURRENCY = {
  US: "USD", GB: "GBP", DE: "EUR", FR: "EUR", JP: "JPY",
  IN: "INR", BR: "BRL", AU: "AUD", CA: "CAD", CN: "CNY",
  KR: "KRW", MX: "MXN", SE: "SEK", CH: "CHF", SG: "SGD",
};

async function currencyMiddleware(req, res, next) {
  const ip = req.headers["x-forwarded-for"]?.split(",")[0] || req.ip;

  try {
    const response = await fetch("https://api.botoi.com/v1/ip/lookup", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Api-Key": process.env.BOTOI_API_KEY,
      },
      body: JSON.stringify({ ip }),
    });

    const { data } = await response.json();
    req.defaultCurrency = COUNTRY_CURRENCY[data.country] || "USD";
  } catch {
    req.defaultCurrency = "USD";
  }

  next();
}

// Usage in Express
app.get("/checkout", currencyMiddleware, (req, res) => {
  res.render("checkout", { currency: req.defaultCurrency });
});

تغطي خريطة الدولة إلى العملة أفضل 15 سوقًا لبرامج SaaS. توسيع نطاقه لجمهورك. يعالج الرجوع إلى الدولار الأمريكي فشل واجهة برمجة التطبيقات (API) بأمان؛ لا يرى أي زائر على الإطلاق الخروج مكسورًا نظرًا لانتهاء مهلة مكالمة تحديد الموقع الجغرافي.

الميزة 2: لافتة ملفات تعريف الارتباط الخاصة باللائحة العامة لحماية البيانات (GDPR) لزوار الاتحاد الأوروبي فقط

إن عرض لافتة الموافقة على ملفات تعريف الارتباط لكل زائر أمر غير ضروري ومزعج. ينطبق القانون العام لحماية البيانات (GDPR) على الزوار في الاتحاد الأوروبي. يمكن لأي شخص آخر تخطيها.

تتحقق هذه البرامج الوسيطة من دولة الملكية الفكرية للزائر ومقارنتها بقائمة الدول الأعضاء في الاتحاد الأوروبي ويقوم بتعيين ملف تعريف ارتباط تقرأه الواجهة الأمامية:

const EU_COUNTRIES = new Set([
  "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR",
  "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL",
  "PL", "PT", "RO", "SK", "SI", "ES", "SE",
]);

async function gdprMiddleware(req, res, next) {
  const ip = req.headers["x-forwarded-for"]?.split(",")[0] || req.ip;

  try {
    const response = await fetch("https://api.botoi.com/v1/ip/lookup", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Api-Key": process.env.BOTOI_API_KEY,
      },
      body: JSON.stringify({ ip }),
    });

    const { data } = await response.json();
    req.isEU = EU_COUNTRIES.has(data.country);
  } catch {
    // Default to showing the banner when the lookup fails
    req.isEU = true;
  }

  next();
}

// Set a cookie so the frontend knows whether to show the banner
app.use(gdprMiddleware, (req, res, next) => {
  res.cookie("gdpr_applies", req.isEU ? "1" : "0", {
    httpOnly: false,
    maxAge: 86400 * 1000,
  });
  next();
});

في الواجهة الأمامية، اقرأ ملف تعريف الارتباط وقم بتبديل الشعار:

// Frontend: read the cookie and conditionally show the banner
function shouldShowCookieBanner() {
  const match = document.cookie.match(/gdpr_applies=(\d)/);
  return match ? match[1] === "1" : true; // default to showing
}

if (shouldShowCookieBanner()) {
  document.getElementById("cookie-banner").style.display = "block";
}

السلوك الافتراضي عند الفشل هو إظهار الشعار. وهذا يخطئ من ناحية الامتثال؛ إذا فشل البحث الجغرافي، فإنك لا تزال تستوفي متطلبات القانون العام لحماية البيانات (GDPR). مدة صلاحية البسكويت 24 ساعة، لذلك يمكنك الاتصال بواجهة برمجة التطبيقات (API) مرة واحدة فقط لكل زائر يوميًا.

الميزة 3: كشف الاحتيال مع عدم التطابق الجغرافي

عندما يقوم شخص ما بالتحقق من عنوان إرسال الفواتير في ألمانيا ولكن يتم تحديد الموقع الجغرافي لعنوان IP الخاص به نيجيريا، هذه إشارة تستحق التحقيق. هذا لا يعني أن الصفقة احتيالي؛ يسافر الأشخاص ويستخدمون الشبكات الافتراضية الخاصة (VPN) ويشترون الهدايا لأصدقائهم في الخارج. لكنها بيانات أشر إلى احتياجات فريق مراجعة الاحتيال الخاص بك.

async function checkGeoMismatch(ip, billingCountry) {
  const response = await fetch("https://api.botoi.com/v1/ip/lookup", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Api-Key": process.env.BOTOI_API_KEY,
    },
    body: JSON.stringify({ ip }),
  });

  const { data } = await response.json();

  const mismatch = data.country !== billingCountry;

  return {
    mismatch,
    ipCountry: data.country,
    ipCity: data.city,
    billingCountry,
    riskNote: mismatch
      ? \`IP located in \${data.countryName} but billing address is \${billingCountry}\`
      : null,
  };
}

// Usage during checkout
app.post("/checkout", async (req, res) => {
  const ip = req.headers["x-forwarded-for"]?.split(",")[0] || req.ip;
  const { billingCountry } = req.body;

  const geo = await checkGeoMismatch(ip, billingCountry);

  if (geo.mismatch) {
    // Flag for manual review instead of blocking
    await flagOrder(req.body.orderId, geo.riskNote);
  }

  // Continue processing the order
  await processOrder(req.body);
  res.json({ success: true });
});

تقوم الدالة بإرجاع كائن منظم مع علامة عدم تطابق ويمكن قراءته بواسطة الإنسان ملاحظة المخاطر التي يمكن لفريق الدعم الخاص بك مراجعتها. قم بوضع علامة على الطلب للمراجعة اليدوية بدلاً من ذلك منعه بشكل قاطع. ادمج هذا مع إشارات أخرى (عمر مجال البريد الإلكتروني، الدفع السرعة، بصمة الجهاز) للحصول على صورة أكثر اكتمالا.

الميزة 4: لوحة تحكم التحليلات مع توزيع المستخدمين

تساعدك معرفة مكان تواجد المستخدمين في تحديد اللغات التي تريد دعمها والمناطق لاستهدافها بالتسويق ومكان وضع خوادم الحافة. يعالج هذا البرنامج النصي دفعة لعناوين IP للزائرين وتنتج توزيعًا مصنفًا للبلد:

async function buildCountryDistribution(ips) {
  const counts = {};

  // Process in batches to respect rate limits
  for (const ip of ips) {
    try {
      const response = await fetch("https://api.botoi.com/v1/ip/lookup", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Api-Key": process.env.BOTOI_API_KEY,
        },
        body: JSON.stringify({ ip }),
      });

      const { data } = await response.json();
      const country = data.countryName || "Unknown";
      counts[country] = (counts[country] || 0) + 1;
    } catch {
      counts["Unknown"] = (counts["Unknown"] || 0) + 1;
    }
  }

  // Sort by count descending
  return Object.entries(counts)
    .sort(([, a], [, b]) => b - a)
    .map(([country, count]) => ({
      country,
      count,
      percentage: ((count / ips.length) * 100).toFixed(1) + "%",
    }));
}

// Example output:
// [
//   { country: "United States", count: 4521, percentage: "34.2%" },
//   { country: "Germany", count: 1893, percentage: "14.3%" },
//   { country: "United Kingdom", count: 1247, percentage: "9.4%" },
//   ...
// ]

قم بتشغيل هذا كمهمة ليلية مقابل سجلات الوصول الخاصة بك. يخبرك الإخراج بالضبط البلدان التي تقود معظم حركة المرور. إذا كان 14% من مستخدميك موجودين في ألمانيا ولكن تطبيقك فقط يدعم اللغة الإنجليزية، وهذه فرصة للترجمة يمكنك قياسها.

استراتيجية التخزين المؤقت

لا تتغير تعيينات IP إلى الموقع كثيرًا. ليس هناك سبب لاستدعاء API مرة أخرى لنفس IP خلال الجلسة. تستخدم ذاكرة التخزين المؤقت هذه خريطة بسيطة مع مدة البقاء لمدة ساعة واحدة:

class GeoCache {
  constructor(ttlMs = 60 * 60 * 1000) {
    this.cache = new Map();
    this.ttlMs = ttlMs;
  }

  get(ip) {
    const entry = this.cache.get(ip);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > this.ttlMs) {
      this.cache.delete(ip);
      return null;
    }
    return entry.data;
  }

  set(ip, data) {
    this.cache.set(ip, { data, timestamp: Date.now() });
  }
}

const geoCache = new GeoCache();

async function lookupWithCache(ip) {
  const cached = geoCache.get(ip);
  if (cached) return cached;

  const response = await fetch("https://api.botoi.com/v1/ip/lookup", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Api-Key": process.env.BOTOI_API_KEY,
    },
    body: JSON.stringify({ ip }),
  });

  const { data } = await response.json();
  geoCache.set(ip, data);
  return data;
}

بالنسبة لخوادم Node.js أحادية المثيل، تعمل الخريطة الموجودة في الذاكرة بشكل جيد. إذا قمت بتشغيل متعددة في المثيلات الموجودة خلف موازن التحميل، استبدل الخريطة بـ Redis. ينطبق نفس منطق TTL؛ قم بتخزين البيانات الجغرافية كسلسلة JSON مع انتهاء صلاحية 3600 ثانية.

استخراج IP العميل

الجزء الأصعب في تحديد الموقع الجغرافي عبر IP ليس استدعاء واجهة برمجة التطبيقات (API)؛ إنه يحصل على عنوان IP الصحيح في المقام الأول. إذا كان تطبيقك موجودًا خلف وكيل عكسي، أو موازن التحميل، أو CDN، req.connection.remoteAddress يقوم بإرجاع عنوان IP الخاص بالوكيل، وليس عنوان الزائر.

إليك كيفية الحصول على عنوان IP الحقيقي للعميل في كل بيئة:

// Express
const ip = req.headers["x-forwarded-for"]?.split(",")[0]?.trim() || req.ip;

// Next.js (App Router)
import { headers } from "next/headers";
const headerList = await headers();
const ip = headerList.get("x-forwarded-for")?.split(",")[0]?.trim();

// Cloudflare Workers
const ip = request.headers.get("cf-connecting-ip");

// Vercel (edge or serverless)
const ip = request.headers.get("x-real-ip")
  || request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();

قم دائمًا بالتقسيم عند الفاصلة الأولى x-forwarded-for. يمكن أن يحتوي هذا الرأس a chain of IPs when traffic passes through multiple proxies. الإدخال الأول هو IP العميل الأصلي.

إذا كنت تستخدم Cloudflare، فاستخدم cf-connecting-ip. يقوم Cloudflare بتعيين هذا الرأس عند كل طلب، ويكون الخداع أصعب من ذلك x-forwarded-for.

FAQ

كيف يمكنني إضافة الموقع الجغرافي IP إلى تطبيق SaaS الخاص بي؟
أرسل عنوان IP الخاص بزائرك إلى واجهة برمجة تطبيقات تحديد الموقع الجغرافي لـ IP (مثل POST /v1/ip/lookup) واستخدم بيانات البلد والمدينة والمنطقة الزمنية التي تم إرجاعها لتخصيص تجربته. تشمل حالات الاستخدام الشائعة الاختيار التلقائي للعملة عند الخروج، وعرض لافتات القانون العام لحماية البيانات (GDPR) لزوار الاتحاد الأوروبي، ووضع علامة على الاحتيال في عدم التطابق الجغرافي، وإنشاء لوحات معلومات تحليلية. يمكنك إضافة الميزات الأربع جميعها باستخدام واجهة برمجة التطبيقات (API) واحدة.
ما هي أفضل واجهة برمجة تطبيقات لموقع IP لمنتجات SaaS؟
ابحث عن واجهة برمجة التطبيقات (API) التي تعرض بيانات البلد والمدينة والمنطقة والإحداثيات والمنطقة الزمنية ومزود خدمة الإنترنت في مكالمة واحدة. يقوم Botoi's /v1/ip/lookup بإرجاع جميع هذه الحقول دون الحاجة إلى تسجيل للوصول المجهول (5 متطلبات/دقيقة). لاستخدام الإنتاج، يوفر مفتاح API المجاني 1000 طلب يوميًا. تبدأ الخطط المدفوعة بسعر 9 دولارات شهريًا.
هل يمكنني تحديد الموقع الجغرافي للمستخدمين عن طريق IP بدون خرائط Google؟
نعم. تقوم واجهات برمجة التطبيقات لتحديد الموقع الجغرافي IP بإرجاع بيانات خطوط الطول والعرض والمدينة والبلد دون الحاجة إلى خرائط Google أو أي خدمة رسم خرائط. You only need a mapping library if you want to display the location on a visual map. بالنسبة إلى ميزات مثل الإعدادات الافتراضية للعملة، والامتثال للقانون العام لحماية البيانات (GDPR)، واكتشاف الاحتيال، فإن بيانات الموقع الجغرافي الأولية من واجهة برمجة التطبيقات (API) هي كل ما تحتاجه.
ما مدى دقة تحديد الموقع الجغرافي عبر IP لاكتشاف موقع المستخدم؟
يكون تحديد الموقع الجغرافي عبر بروتوكول الإنترنت دقيقًا على مستوى الدولة في حوالي 99% من الوقت وعلى مستوى المدينة في حوالي 80-90% من الوقت. تنخفض الدقة بالنسبة لشركات الجوال ومستخدمي VPN. بالنسبة لميزات SaaS مثل اختيار العملة والامتثال للقانون العام لحماية البيانات، تكون الدقة على مستوى الدولة كافية. للكشف عن الاحتيال، اجمع بين تحديد الموقع الجغرافي عبر IP وبيانات عنوان إرسال الفواتير بدلاً من الاعتماد على الدقة على مستوى المدينة.
هل يجب أن أقوم بتخزين نتائج تحديد الموقع الجغرافي لـ IP في SaaS الخاص بي؟
نعم. تتغير تعيينات IP إلى الموقع بشكل غير متكرر، لذا فإن التخزين المؤقت للنتائج لمدة ساعة واحدة لكل IP يقلل من استدعاءات واجهة برمجة التطبيقات (API) بشكل كبير. استخدم خريطة في الذاكرة لعمليات نشر مثيل واحد أو Redis لعمليات إعداد مثيلات متعددة. تشهد معظم تطبيقات SaaS معدلات وصول إلى ذاكرة التخزين المؤقت تتراوح من 60 إلى 80% نظرًا لأن الزائرين العائدين وصلوا إلى نفس عنوان IP خلال الجلسة.

ابدأ البناء مع botoi

أكثر من 150 نقطة نهاية API للبحث ومعالجة النصوص وتوليد الصور وأدوات المطورين. باقة مجانية، بدون بطاقة ائتمان.