NextAITeam commited on
Commit
d2ba5e3
·
verified ·
1 Parent(s): 59fc84f

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +41 -31
server.js CHANGED
@@ -8,26 +8,25 @@ const PORT = 7860;
8
  const CACHE_TTL = 3600;
9
  const cache = new Map();
10
 
11
- // ===== تابع برای Decode کردن URL از /api/click =====
12
- function decodeDestUrl(clickUrl) {
13
- if (!clickUrl || !clickUrl.startsWith('/api/click')) {
14
- return clickUrl;
15
  }
 
16
  try {
17
- const urlParams = new URL(`https://search.bertina.ir${clickUrl}`);
18
- const dest = urlParams.searchParams.get('dest');
19
  if (dest) {
20
- // Decode Base64
21
- const decoded = Buffer.from(dest, 'base64').toString('utf-8');
22
- return decoded;
23
  }
24
- } catch (e) {
25
- console.error('Error decoding dest URL:', e.message);
 
26
  }
27
- return clickUrl;
28
  }
29
 
30
- // ===== استخراج نتایج معمولی با Cheerio =====
31
  async function searchBertinaOrganic(query) {
32
  const url = `https://search.bertina.ir/search?q=${encodeURIComponent(query)}`;
33
  console.log(`🔍 Fetching organic results from Bertina...`);
@@ -51,21 +50,18 @@ async function searchBertinaOrganic(query) {
51
 
52
  const link = $(el).find('h3 a');
53
  const title = link.text().trim();
54
- let href = link.attr('href') || '';
55
  const domain = $(el).find('cite.not-italic').text().trim();
56
  const snippet = $(el).find('p.mt-1.text-sm').text().trim();
57
 
58
- // ===== تصحیح URL =====
59
- if (href) {
60
- href = decodeDestUrl(href);
61
- }
62
-
63
  if (title && href) {
 
 
64
  results.push({
65
  title: title.slice(0, 200),
66
- url: href,
67
  snippet: snippet.slice(0, 300),
68
- site: domain || new URL(href).hostname.replace('www.', '')
69
  });
70
  }
71
  });
@@ -78,7 +74,7 @@ async function searchBertinaOrganic(query) {
78
  }
79
  }
80
 
81
- // ===== استخراج پاسخ هوش مصنوعی با Playwright =====
82
  async function searchBertinaAI(query) {
83
  console.log(`🤖 Fetching AI answer with Playwright...`);
84
  let browser;
@@ -94,9 +90,9 @@ async function searchBertinaAI(query) {
94
  timeout: 30000
95
  });
96
 
97
- // منتظر می‌مانیم تا پاسخ هوش مصنوعی بارگذاری شود
98
  try {
99
- await page.waitForSelector('aside[aria-label="پاسخ هوش مصنوعی"] .text-sm', {
100
  timeout: 10000
101
  });
102
  } catch (e) {
@@ -104,16 +100,30 @@ async function searchBertinaAI(query) {
104
  return null;
105
  }
106
 
107
- // استخراج متن پاسخ از <div> داخل aside
 
108
  const aiAnswer = await page.$eval(
109
- 'aside[aria-label="پاسخ هوش مصنوعی"] .text-sm',
110
  el => el.textContent.trim()
111
  ).catch(() => null);
112
 
113
- if (aiAnswer && aiAnswer.length > 10 && !aiAnswer.includes('در حال تفکر')) {
114
- console.log(`✅ AI answer extracted: ${aiAnswer.slice(0, 50)}...`);
115
- return aiAnswer;
 
 
 
 
116
  }
 
 
 
 
 
 
 
 
 
117
  return null;
118
 
119
  } catch (error) {
@@ -166,7 +176,7 @@ async function search(query) {
166
  const output = {
167
  query,
168
  results,
169
- ai_answer: aiAnswer || null,
170
  source: results.length > 0 ? 'bertina' : 'duckduckgo'
171
  };
172
 
@@ -199,7 +209,7 @@ app.get('/', (req, res) => {
199
  res.json({
200
  status: 'running',
201
  usage: '/search?q=YOUR_QUERY',
202
- note: 'Bertina search + AI answer with Playwright'
203
  });
204
  });
205
 
 
8
  const CACHE_TTL = 3600;
9
  const cache = new Map();
10
 
11
+ // ===== تابع تبدیل URL برتینا به لینک واقعی =====
12
+ function decodeBertinaUrl(bertinaUrl) {
13
+ if (!bertinaUrl || !bertinaUrl.startsWith('/api/click')) {
14
+ return bertinaUrl;
15
  }
16
+
17
  try {
18
+ const url = new URL(bertinaUrl, 'https://search.bertina.ir');
19
+ const dest = url.searchParams.get('dest');
20
  if (dest) {
21
+ return Buffer.from(dest, 'base64').toString('utf-8');
 
 
22
  }
23
+ return bertinaUrl;
24
+ } catch {
25
+ return bertinaUrl;
26
  }
 
27
  }
28
 
29
+ // ===== استخراج نتایج ارگانیک =====
30
  async function searchBertinaOrganic(query) {
31
  const url = `https://search.bertina.ir/search?q=${encodeURIComponent(query)}`;
32
  console.log(`🔍 Fetching organic results from Bertina...`);
 
50
 
51
  const link = $(el).find('h3 a');
52
  const title = link.text().trim();
53
+ const href = link.attr('href') || '';
54
  const domain = $(el).find('cite.not-italic').text().trim();
55
  const snippet = $(el).find('p.mt-1.text-sm').text().trim();
56
 
 
 
 
 
 
57
  if (title && href) {
58
+ // تبدیل URL به لینک واقعی
59
+ const realUrl = decodeBertinaUrl(href);
60
  results.push({
61
  title: title.slice(0, 200),
62
+ url: realUrl,
63
  snippet: snippet.slice(0, 300),
64
+ site: domain || new URL(realUrl).hostname.replace('www.', '')
65
  });
66
  }
67
  });
 
74
  }
75
  }
76
 
77
+ // ===== استخراج پاسخ هوش مصنوعی =====
78
  async function searchBertinaAI(query) {
79
  console.log(`🤖 Fetching AI answer with Playwright...`);
80
  let browser;
 
90
  timeout: 30000
91
  });
92
 
93
+ // منتظر می‌مانیم تا بخش پاسخ هوش مصنوعی بارگذاری شود
94
  try {
95
+ await page.waitForSelector('aside[aria-label="پاسخ هوش مصنوعی"]', {
96
  timeout: 10000
97
  });
98
  } catch (e) {
 
100
  return null;
101
  }
102
 
103
+ // استخراج متن پاسخ با سلکتور دقیق‌تر
104
+ // متن پاسخ داخل یک div با کلاس text-sm leading-relaxed قرار دارد
105
  const aiAnswer = await page.$eval(
106
+ 'aside[aria-label="پاسخ هوش مصنوعی"] .text-sm.leading-relaxed',
107
  el => el.textContent.trim()
108
  ).catch(() => null);
109
 
110
+ // اگر با سلکتور بالا پیدا نشد، از سلکتور جایگزین استفاده کن
111
+ let aiAnswer2 = null;
112
+ if (!aiAnswer || aiAnswer.length < 10) {
113
+ aiAnswer2 = await page.$eval(
114
+ 'aside[aria-label="پاسخ هوش مصنوعی"] .space-y-2',
115
+ el => el.textContent.trim()
116
+ ).catch(() => null);
117
  }
118
+
119
+ const finalAnswer = aiAnswer || aiAnswer2;
120
+
121
+ if (finalAnswer && finalAnswer.length > 10 && !finalAnswer.includes('در حال تفکر')) {
122
+ console.log(`✅ AI answer extracted: ${finalAnswer.slice(0, 50)}...`);
123
+ return finalAnswer;
124
+ }
125
+
126
+ console.log('⏭️ AI answer content is empty or still loading');
127
  return null;
128
 
129
  } catch (error) {
 
176
  const output = {
177
  query,
178
  results,
179
+ ai_answer: aiAnswer,
180
  source: results.length > 0 ? 'bertina' : 'duckduckgo'
181
  };
182
 
 
209
  res.json({
210
  status: 'running',
211
  usage: '/search?q=YOUR_QUERY',
212
+ note: 'Bertina search + AI answer + real URLs'
213
  });
214
  });
215