channel-worker 2.5.59 → 2.5.60

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.59",
3
+ "version": "2.5.60",
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": {
@@ -96,6 +96,18 @@ async function humanClick(page, target, { hoverMs = [250, 900], timeout = 4000,
96
96
  await page.waitForTimeout(randInt(hoverMs[0], hoverMs[1]));
97
97
  // Tiny drift while "deciding" — people rarely hold a pixel.
98
98
  if (chance(0.5)) await page.mouse.move(p.x + rand(-1.5, 1.5), p.y + rand(-1.5, 1.5)).catch(() => {});
99
+ // KIỂM TRA VẬT CẢN trước khi nhấn — thứ Playwright làm ở loc.click() mà
100
+ // đường "kiểu người" này bỏ qua. 23/08 đăng FB fail 3 lượt liên tiếp: toast
101
+ // "Thông báo mới" nổi vài giây đúng góc dưới-trái, trùng nút "Tiếp" của
102
+ // composer; mouse.down rơi vào toast → FB mở reel, composer kẹt ở bước 1.
103
+ // Vật cản thường tự tan → chờ tới 6s; vẫn còn thì giao cho click chuẩn (có
104
+ // actionability + retry của Playwright) thay vì nhấn bừa.
105
+ const blocked = () => target.evaluate((el, pt) => {
106
+ const h = document.elementFromPoint(pt.x, pt.y);
107
+ return !(h && (el === h || el.contains(h) || h.contains(el)));
108
+ }, p).catch(() => false);
109
+ for (let i = 0; i < 12 && await blocked(); i++) await page.waitForTimeout(500);
110
+ if (await blocked()) { await target.click({ timeout }); return; }
99
111
  await page.mouse.down();
100
112
  await page.waitForTimeout(randInt(55, 140));
101
113
  await page.mouse.up();
@@ -1233,7 +1233,8 @@ async function runOnce({ page, payload, log }) {
1233
1233
  // iterations, throw with diagnostics.
1234
1234
  let published = false;
1235
1235
  let customThumbDone = false;
1236
- let pubWaitDone = false; // guard: wait for a disabled "Đăng" at most once
1236
+ let pubWaitDone = false;
1237
+ let reelViewerRecoveries = 0; // bấm Tiếp trượt vào toast → FB mở reel viewer, xem bên dưới
1237
1238
  for (let step = 0; step < 7 && !published; step++) {
1238
1239
  await pause(page, 3000);
1239
1240
  await fillMetadata();
@@ -2145,6 +2146,21 @@ async function runOnce({ page, payload, log }) {
2145
2146
  await dumpFailure(page, `tiep-not-clickable-${step + 1}`, log);
2146
2147
  throw new Error(`FB Tiếp not clickable at step ${step + 1}: ${e.message}`);
2147
2148
  }
2149
+ // Cú bấm trượt vào thứ khác (toast thông báo / mục thông báo) → FB mở
2150
+ // reel viewer đè lên, nhưng composer VẪN CÒN ở bước cũ (kiểm kê 23/08:
2151
+ // dialog "Tạo thước phim… Tiếp" vẫn đó bên dưới viewer). Đóng viewer
2152
+ // bằng Escape rồi bấm lại — khỏi phải chạy lại cả lượt upload.
2153
+ if (/\/reel\/\d+/.test(page.url()) && (await composerStepLabel()) === stepLabelBefore && stepLabelBefore) {
2154
+ reelViewerRecoveries++;
2155
+ log('warn', `[fb-pw] bấm Tiếp bị trượt → FB mở reel viewer (${page.url().slice(0, 60)}), composer vẫn ở bước cũ — đóng viewer, bấm lại (${reelViewerRecoveries}/3)`);
2156
+ await page.keyboard.press('Escape').catch(() => {});
2157
+ await page.waitForTimeout(1500);
2158
+ if (/\/reel\/\d+/.test(page.url())) {
2159
+ await page.locator("[aria-label='Đóng'], [aria-label='Close']").first().click({ timeout: 3000 }).catch(() => {});
2160
+ await page.waitForTimeout(1500);
2161
+ }
2162
+ if (reelViewerRecoveries <= 3 && await hasVisibleReelComposer(page)) { step--; continue; }
2163
+ }
2148
2164
 
2149
2165
  // BS-only side-wizard jump fallback — DO NOT run in Page-wall mode.
2150
2166
  // The BS composer has a left-side wizard with clickable step headers