channel-worker 2.5.127 → 2.5.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -292,13 +292,30 @@ async function scrapeOffers(ctx, {
292
292
  category = null, // key in AFFILIATE_CATEGORIES (e.g. 'women_clothes')
293
293
  match_id = null, // explicit category id override
294
294
  // Tìm theo TỪ KHOÁ thay vì duyệt tab ngành hàng. Cùng endpoint, khác tham số:
295
- // `list_type=0&keyword=<kw>&filter_types=2` (đo 09/09/2026 — ghi chú cũ bảo
296
- // "cần signed header" là sai/lạc hậu).
295
+ // `list_type=0&keyword=<kw>` (đo 09/09/2026 — ghi chú cũ bảo "cần signed
296
+ // header" là sai/lạc hậu). Bản đầu còn kèm `filter_types=2`; 22/09 đo ra nó
297
+ // cắt mất 5/7 món và giao diện thật không hề gửi — xem ghi chú ở tham số
298
+ // `filter_types` bên dưới.
297
299
  //
298
300
  // Đây là thứ gỡ bế tắc kho bão hoà: 6 tab ngành hàng luôn trả về top N giống
299
301
  // nhau nên kho đứng yên ở 34 sản phẩm. Từ khoá thì mở ra đúng món hợp với
300
302
  // từng video.
301
303
  keyword = null,
304
+ // Bộ lọc của chính trang affiliate. Để null = KHÔNG lọc, đúng như giao diện.
305
+ //
306
+ // Đo 22/09/2026 trên profile Shopee1, từ khoá "vợt bắt hải sản":
307
+ // filter_types=2 → 2 món ← thứ mình gắn cứng từ 09/09
308
+ // không filter → 7 món ← thứ GIAO DIỆN thật sự gọi
309
+ // filter_types=0/1/3 → 0 món
310
+ // `filter_types=2` = chỉ lấy món người bán TỰ CỘNG hoa hồng
311
+ // (`seller_commission_rate > 0`): 2 món lọt có seller 7% và 4%, 5 món bị
312
+ // giấu đều seller 0% nhưng default 7%. Tức nó vứt phần lớn thị trường.
313
+ //
314
+ // Bắt tận tay bằng cách cho giao diện tự tìm rồi nghe request nó gửi:
315
+ // /api/v3/offer/product/list?list_type=0&keyword=…&sort_type=1
316
+ // &page_offset=0&page_limit=20&client_type=1
317
+ // — không có filter_types. Mình tự thêm vào, và tự làm hẹp kết quả.
318
+ filter_types = null,
302
319
  sort_types = [2], // [2]=commission; pass [2,3] to merge commission+sales
303
320
  pages = 2,
304
321
  page_limit = 20,
@@ -357,7 +374,7 @@ async function scrapeOffers(ctx, {
357
374
  // thì Shopee bỏ qua keyword và mình tưởng đang tìm mà thật ra vẫn
358
375
  // đang duyệt tab cũ.
359
376
  const cat = q.kw
360
- ? `&list_type=0&keyword=${encodeURIComponent(q.kw)}&filter_types=2`
377
+ ? `&list_type=0&keyword=${encodeURIComponent(q.kw)}${q.ft != null ? `&filter_types=${q.ft}` : ''}`
361
378
  : (q.listType
362
379
  ? `&list_type=${q.listType}`
363
380
  : (q.mid ? `&list_type=3&match_type=2&match_id=${q.mid}` : '&list_type=0'));
@@ -366,7 +383,7 @@ async function scrapeOffers(ctx, {
366
383
  const r = await fetch(url, { credentials: 'include' });
367
384
  return { status: r.status, json: await r.json().catch(() => null) };
368
385
  } catch (e) { return { status: 0, error: String(e.message) }; }
369
- }, { st, offset, page_limit, mid, listType, kw });
386
+ }, { st, offset, page_limit, mid, listType, kw, ft: filter_types });
370
387
 
371
388
  if (isBlockedState(page.url(), res) || res.json?.code === 90309999) {
372
389
  return { status: 'needs_verify', products: [...byId.values()], raw_count: rawCount, reason: `blocked mid-scrape (http ${res.status}, code ${res.json?.code})` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.5.127",
3
+ "version": "2.5.128",
4
4
  "description": "Channel Manager worker daemon — runs on remote machines to execute video pipeline jobs",
5
5
  "main": "lib/daemon.js",
6
6
  "bin": {