channel-worker 2.5.97 → 2.5.98

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.5.97",
3
+ "version": "2.5.98",
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": {
@@ -700,7 +700,10 @@ async function discoverReelsTabUrl(page, log = null) {
700
700
  for (const a of document.querySelectorAll('a[href]')) {
701
701
  const href = a.getAttribute('href') || '';
702
702
  if (!href || href.startsWith('#') || href.startsWith('javascript:')) continue;
703
- out.push({ href: href.slice(0, 200), aria: (a.getAttribute('aria-label') || '').slice(0, 80) });
703
+ // Anchor nằm trong bảng tin / một bài viết → của page KHÁC, không phải
704
+ // của mình (xem ghi chú ở pickReelsTabUrl).
705
+ const inFeed = !!a.closest("[role='feed'], [role='article'], [aria-posinset]");
706
+ out.push({ href: href.slice(0, 200), aria: (a.getAttribute('aria-label') || '').slice(0, 80), inFeed });
704
707
  if (out.length >= 400) break;
705
708
  }
706
709
  return out;
@@ -754,7 +757,17 @@ function isComposerDialogSignature(text) {
754
757
  // 2/2 lượt "không tìm được link tab Reels trước khi đăng". Trang chủ của Page
755
758
  // có shortcut bên trái trỏ /<id số>/ hoặc /<handle>/, và đôi khi /<id>/reels/.
756
759
  function pickReelsTabUrl(anchors) {
757
- const list = (anchors || []).map((a) => ({ href: String(a.href || ''), aria: String(a.aria || '') }));
760
+ const list = (anchors || [])
761
+ .map((a) => ({ href: String(a.href || ''), aria: String(a.aria || ''), inFeed: !!a.inFeed }))
762
+ // ⛔ LOẠI anchor CỦA BÀI TRONG BẢNG TIN — đây là gốc của 2 link sai sáng
763
+ // 10/09 (kênh "kol du lịch 2", reel 1712630710026375 và 1549470359802337
764
+ // hoá ra là bài của PAGE LẠ). Trang chủ đầy bài của page khác; mỗi bài có
765
+ // link /profile.php?id=<page lạ>&__cft__[0]=… nên chiến lược 2 bốc trúng
766
+ // tab Reels của người ta, rồi "so trước/sau" so hai page khác nhau (log:
767
+ // "trước 10, sau 10, mới 10 — nhiều hơn 1, không nhận") và nhánh gói mạng
768
+ // chốt bằng reel gợi ý trên feed. Dấu nhận biết: tham số __cft__/__tn__
769
+ // (tracking của một bài cụ thể) hoặc anchor nằm trong vùng feed/article.
770
+ .filter((a) => !a.inFeed && !/[?&]__cft__|[?&]__tn__/.test(a.href));
758
771
  const abs = (h) => (h.startsWith('http') ? h : `https://www.facebook.com${h}`);
759
772
  for (const a of list) if (/sk=reels_tab/.test(a.href)) return abs(a.href);
760
773
  for (const a of list) {
@@ -2845,6 +2858,7 @@ async function runOnce({ page, payload, log }) {
2845
2858
  return null;
2846
2859
  }).catch(() => null);
2847
2860
  let reelsTabUrl = null; // giữ lại cho lượt retry (a.2b)
2861
+ let networkCandidate = null; // ID gói mạng chưa được tab Reels xác nhận
2848
2862
  try {
2849
2863
  // Find a link to the page's reels tab. Multi-strategy:
2850
2864
  // 1. Any existing href containing "sk=reels_tab"
@@ -2987,9 +3001,21 @@ async function runOnce({ page, payload, log }) {
2987
3001
  const preSet = new Set(capturedReelIds.slice(0, capturedReelIdsSnapshotLen));
2988
3002
  const trulyNew = newIds.filter((id) => !preSet.has(id));
2989
3003
  if (trulyNew.length) {
3004
+ // ⚠️ ID bắt từ gói mạng KHÔNG chứng minh reel thuộc page mình: đứng ở
3005
+ // trang chủ, feed tải liên tục reel GỢI Ý của page khác, nên "ID mới
3006
+ // đầu tiên sau mốc" có thể là reel người ta (sáng 10/09: snapshotLen=132,
3007
+ // total=220 → 88 ID mới, cái đầu là reel của page lạ và đã bị ghi vào DB).
3008
+ // Chỉ nhận khi tab Reels CỦA CHÍNH PAGE xác nhận có ID đó; không xác
3009
+ // nhận được thì để làm ứng viên, lượt chờ 75s dưới đây kiểm lại.
2990
3010
  const firstNew = trulyNew[0];
2991
- postUrl = `https://www.facebook.com/reel/${firstNew}/`;
2992
- log('info', `[fb-pw] post URL from network (FIRST new ID after snapshot): ${postUrl} (snapshotLen=${capturedReelIdsSnapshotLen} total=${capturedReelIds.length} new=${trulyNew.length})`);
3011
+ const tabIds = reelsTabUrl ? await scrapeReelTileIds(page) : [];
3012
+ if (tabIds.includes(firstNew)) {
3013
+ postUrl = `https://www.facebook.com/reel/${firstNew}/`;
3014
+ log('info', `[fb-pw] post URL from network + tab Reels xác nhận: ${postUrl} (snapshotLen=${capturedReelIdsSnapshotLen} total=${capturedReelIds.length} new=${trulyNew.length})`);
3015
+ } else {
3016
+ networkCandidate = firstNew;
3017
+ log('warn', `[fb-pw] gói mạng cho ID ${firstNew} nhưng tab Reels của page CHƯA xác nhận (${tabIds.length} tile) — giữ làm ứng viên, chờ kiểm lại`);
3018
+ }
2993
3019
  }
2994
3020
  }
2995
3021
 
@@ -3008,6 +3034,9 @@ async function runOnce({ page, payload, log }) {
3008
3034
  if (fresh2) {
3009
3035
  postUrl = fresh2.href.startsWith('http') ? fresh2.href : `https://www.facebook.com${fresh2.href}`;
3010
3036
  log('info', `[fb-pw] post URL from reels_tab RETRY (id=${fresh2.id}, timestamp="${fresh2.timestamp}"): ${postUrl}`);
3037
+ } else if (networkCandidate && (await scrapeReelTileIds(page)).includes(networkCandidate)) {
3038
+ postUrl = `https://www.facebook.com/reel/${networkCandidate}/`;
3039
+ log('info', `[fb-pw] post URL: ứng viên gói mạng đã được tab Reels xác nhận sau lượt chờ: ${postUrl}`);
3011
3040
  } else if (reelIdsBefore) {
3012
3041
  const after2 = await scrapeReelTileIds(page);
3013
3042
  const diff2 = diffNewReelIds(reelIdsBefore, after2);