channel-worker 2.5.100 → 2.5.101

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.100",
3
+ "version": "2.5.101",
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": {
@@ -744,6 +744,19 @@ function diffNewReelIds(beforeIds, afterIds) {
744
744
  return (afterIds || []).filter((id) => !before.has(id));
745
745
  }
746
746
 
747
+ // ID từ gói mạng: tab Reels xác nhận chỉ chứng minh reel THUỘC PAGE MÌNH, không
748
+ // chứng minh nó MỚI. Ca 10/09 16:26 "ẩm thực đồng quê 01": snapshotLen=0 nên cả
749
+ // 40 ID bắt được đều "mới", ID đầu tiên 1600960624772777 có trên tab (là bài
750
+ // 07:55 sáng CỦA CHÍNH KÊNH) → nhận → API thấy link trùng idea khác → gỡ → bài
751
+ // thành "mập mờ". Ảnh nền tab Reels chụp trước khi mở composer là bằng chứng
752
+ // "cũ": ID nằm trong ảnh nền thì KHÔNG BAO GIỜ là bài vừa đăng. Thuần, test được.
753
+ function networkIdVerdict({ id, beforeIds, tabIds }) {
754
+ if (!id) return 'none';
755
+ if ((beforeIds || []).includes(id)) return 'stale'; // đã có trước khi đăng
756
+ if ((tabIds || []).includes(id)) return 'confirmed'; // của page mình và mới
757
+ return 'candidate'; // chưa thấy trên tab, chờ
758
+ }
759
+
747
760
  // Chữ ký của chính composer (mọi bước của wizard). Dùng để KHÔNG bao giờ bấm
748
761
  // nhầm vào nút của composer khi đang định bấm nút của hộp ảnh bìa.
749
762
  const COMPOSER_SIGNATURE_RE = /Cài đặt thước phim|Tạo thước phim|Chỉnh sửa thước phim|Reel settings|Create (?:a )?reel|Edit reel/i;
@@ -1033,7 +1046,15 @@ async function runOnce({ page, payload, log }) {
1033
1046
  log('info', `[fb-pw] after Thước phim click — url=${afterUrl}`);
1034
1047
  // Sanity check: clicking the sidebar Reels link navigates to /reel/<id>.
1035
1048
  // That means we clicked the wrong button — fail fast so the user knows.
1036
- if (/\/reel\/\d+/.test(afterUrl)) {
1049
+ // 10/09 19:12 "phụ kiện điện tử 02": URL thành /reel/1850660615918243 nhưng
1050
+ // ảnh dump cho thấy hộp "Tạo thước phim" (Thêm video / Tải lên) ĐANG MỞ đè
1051
+ // lên feed Reels — Facebook giờ vẽ trình tạo như một lớp phủ trên /reel/<id>
1052
+ // chứ không điều hướng sang /reels/create/. Phán "bị đá về feed" theo URL
1053
+ // là báo oan tài khoản ("cần người đăng nhập thử tay") trong khi composer
1054
+ // đã sẵn sàng. Có composer thì cứ đi tiếp; chỉ khi KHÔNG có mới là bị đá.
1055
+ if (/\/reel\/\d+/.test(afterUrl) && (await hasVisibleReelComposer(page))) {
1056
+ log('info', `[fb-pw] url=/reel/<id> nhưng hộp Tạo thước phim đang mở đè lên feed — không phải bị đá, đi tiếp`);
1057
+ } else if (/\/reel\/\d+/.test(afterUrl)) {
1037
1058
  // HAI nguyên nhân hoàn toàn khác nhau, trước đây gộp chung một câu báo
1038
1059
  // "wrong button matched" — và câu đó gửi người đọc đi tìm lỗi DOM không
1039
1060
  // hề tồn tại (kênh 6a2e66b3 hỏng suốt từ 27/08 vì hiểu nhầm chỗ này):
@@ -3007,14 +3028,19 @@ async function runOnce({ page, payload, log }) {
3007
3028
  // total=220 → 88 ID mới, cái đầu là reel của page lạ và đã bị ghi vào DB).
3008
3029
  // Chỉ nhận khi tab Reels CỦA CHÍNH PAGE xác nhận có ID đó; không xác
3009
3030
  // nhận được thì để làm ứng viên, lượt chờ 75s dưới đây kiểm lại.
3010
- const firstNew = trulyNew[0];
3031
+ // Bỏ qua mọi ID đã có trong ảnh nền (bài cũ của chính mình) — xem
3032
+ // networkIdVerdict. Lấy ID mới đầu tiên KHÔNG nằm trong ảnh nền.
3011
3033
  const tabIds = reelsTabUrl ? await scrapeReelTileIds(page) : [];
3012
- if (tabIds.includes(firstNew)) {
3034
+ const firstNew = trulyNew.find((id) => networkIdVerdict({ id, beforeIds: reelIdsBefore, tabIds }) !== 'stale') || null;
3035
+ const verdict = networkIdVerdict({ id: firstNew, beforeIds: reelIdsBefore, tabIds });
3036
+ if (verdict === 'confirmed') {
3013
3037
  postUrl = `https://www.facebook.com/reel/${firstNew}/`;
3014
3038
  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 {
3039
+ } else if (verdict === 'candidate') {
3016
3040
  networkCandidate = firstNew;
3017
3041
  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`);
3042
+ } else {
3043
+ log('warn', `[fb-pw] gói mạng chỉ có ID đã nằm trong ảnh nền (${trulyNew.length} ID, toàn bài cũ của mình) — không nhận, chờ so trước/sau`);
3018
3044
  }
3019
3045
  }
3020
3046
  }
@@ -3034,7 +3060,7 @@ async function runOnce({ page, payload, log }) {
3034
3060
  if (fresh2) {
3035
3061
  postUrl = fresh2.href.startsWith('http') ? fresh2.href : `https://www.facebook.com${fresh2.href}`;
3036
3062
  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)) {
3063
+ } else if (networkCandidate && networkIdVerdict({ id: networkCandidate, beforeIds: reelIdsBefore, tabIds: await scrapeReelTileIds(page) }) === 'confirmed') {
3038
3064
  postUrl = `https://www.facebook.com/reel/${networkCandidate}/`;
3039
3065
  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}`);
3040
3066
  } else if (reelIdsBefore) {
@@ -3181,6 +3207,7 @@ module.exports.__testables = {
3181
3207
  confirmPublishDialog,
3182
3208
  diffNewReelIds,
3183
3209
  pickReelsTabUrl,
3210
+ networkIdVerdict,
3184
3211
  isComposerDialogSignature,
3185
3212
  discoverReelsTabUrl,
3186
3213
  scrapeReelTileIds,