118 lines
3.2 KiB
JavaScript
118 lines
3.2 KiB
JavaScript
// basalam.js
|
|
const fetch = require("node-fetch"); // نصب با: npm install node-fetch@2
|
|
|
|
// ساخت URL جستجوی Basalam
|
|
function buildUrl(q, from = 0, size =25) {
|
|
const base = "https://services.basalam.com/web/v1/search/product/search";
|
|
const params = new URLSearchParams({
|
|
from: String(from),
|
|
q: q,
|
|
dynamicFacets: "true",
|
|
size: String(size),
|
|
enableNavigations: "true",
|
|
adsImpressionDisable: "false",
|
|
grouped: "true"
|
|
});
|
|
return base + "?" + params.toString();
|
|
}
|
|
|
|
// استخراج آیتمها از JSON پاسخ Basalam
|
|
function extractItems(json) {
|
|
const candidates = [
|
|
json?.data?.products,
|
|
json?.data?.items,
|
|
json?.products,
|
|
json?.items,
|
|
json?.hits,
|
|
json?.groups?.flatMap(g => g.items || g.products || []),
|
|
json?.dynamicFacets?.flatMap(f => f.items || [])
|
|
];
|
|
for (const c of candidates) {
|
|
if (Array.isArray(c) && c.length) return c;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
// نگاشت هر آیتم به ساختار استاندارد
|
|
function mapItem(item) {
|
|
const title =
|
|
item.title ||
|
|
item.name ||
|
|
item.displayName ||
|
|
item.productName ||
|
|
item?.payload?.title ||
|
|
"بدون عنوان";
|
|
|
|
const image = [
|
|
item?.photo?.MEDIUM,
|
|
item?.photo?.SMALL,
|
|
item?.image_url,
|
|
item?.image,
|
|
item?.media?.[0]?.url,
|
|
item?.thumbnail,
|
|
Array.isArray(item?.images) ? item.images[0] : null
|
|
].find(src => typeof src === "string" && src.trim().length > 0) || "https://via.placeholder.com/150";
|
|
|
|
const price =
|
|
item.price ||
|
|
item.unitPrice ||
|
|
item?.payload?.price ||
|
|
item?.minPrice ||
|
|
(item.prices && item.prices.price);
|
|
|
|
const priceText =
|
|
price != null
|
|
? typeof price === "object"
|
|
? price.value || JSON.stringify(price)
|
|
: price
|
|
: "—";
|
|
|
|
const category = item?.categoryTitle || item?.category || "—";
|
|
|
|
return {
|
|
title,
|
|
category,
|
|
price: priceText,
|
|
image,
|
|
description:
|
|
item.description ||
|
|
item.summary ||
|
|
item.details ||
|
|
item.overview ||
|
|
item?.payload?.description ||
|
|
""
|
|
};
|
|
}
|
|
|
|
// تابع اصلی برای جستجوی Basalam
|
|
async function searchBasalam(query, size = 12) {
|
|
if (!query) return [];
|
|
|
|
const url = buildUrl(query, 0, size);
|
|
|
|
const headers = {
|
|
accept: "application/json, text/plain, */*",
|
|
"accept-language": "en-US,en;q=0.9,fa;q=0.8",
|
|
"x-client-info": JSON.stringify({
|
|
version: "3.38.7",
|
|
project: "charsou",
|
|
name: "web.public",
|
|
platform: "web",
|
|
deviceId: "0e238114-80e2-47b4-89d6-2173f7db9b54",
|
|
sessionId: "da951b95-26f2-4b54-bc17-6c82ec110d80"
|
|
})
|
|
};
|
|
|
|
try {
|
|
const resp = await fetch(url, { headers });
|
|
const json = await resp.json();
|
|
const items = extractItems(json).map(mapItem);
|
|
return items;
|
|
} catch (err) {
|
|
console.error("Basalam search error:", err);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// export تابع
|
|
module.exports = { searchBasalam }; |