channel-worker 2.5.10 → 2.5.12

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.10",
3
+ "version": "2.5.12",
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": {
@@ -1319,17 +1319,6 @@ async function run({ page, payload, log }) {
1319
1319
  throw new Error(`FB publish: thumbnail_url provided but the "Chỉnh sửa hình thu nhỏ" overlay was never detected before publish (step ${step + 1}). Refusing to ship without custom thumb. Inspect dump screenshots in Temp\\cm-worker-pw\\.`);
1320
1320
  }
1321
1321
  log('info', `[fb-pw] click publish "${pub.verb}" via "${pub.sel}" (step ${step + 1})`);
1322
- // DRY-RUN MODE (temporary, for QA): skip the actual publish click so
1323
- // we can verify the upstream flow (modal scoping, video upload, thumb
1324
- // step, metadata fill) without spawning real Reels every iteration.
1325
- // Throws a recognisable error so the daemon marks the cmd failed
1326
- // without retrying. REMOVE this block once the page-wall composer
1327
- // fix is verified end-to-end.
1328
- if (process.env.FB_PW_DRY_RUN === '1' || payload._dry_run === true) {
1329
- await dumpInventory(page, log, `dry-run-at-publish-${step + 1}`);
1330
- await dumpFailure(page, `dry-run-at-publish-${step + 1}`, log);
1331
- throw new Error(`[fb-pw] DRY-RUN: reached publish step ${step + 1} successfully. Pub button found via "${pub.sel}" verb="${pub.verb}". Thumb=${customThumbDone ? 'uploaded' : 'NOT uploaded'}. NOT clicking. Inspect dump screenshots in Temp\\cm-worker-pw\\.`);
1332
- }
1333
1322
  // Snapshot the captured-IDs list RIGHT BEFORE the publish click. The
1334
1323
  // network listener captures from EVERY graph response, including the
1335
1324
  // pre-publish page wall feed (~100+ IDs). Only IDs captured AFTER
@@ -515,8 +515,41 @@ async function run({ page, payload, log }) {
515
515
  await jitter(page, 800);
516
516
 
517
517
  // 5) The KEY step — set the video file.
518
- log('info', `[yt-pw] setInputFiles(video)…`);
519
- await page.locator(S.fileInput).setInputFiles(videoPath);
518
+ //
519
+ // Playwright's setInputFiles() over connectOverCDP caps at 50MB. Real
520
+ // shorts are 100–300MB. Bypass via in-browser fetch: the browser pulls
521
+ // the file directly from our media server (CORS-open on redrop) and we
522
+ // assign the resulting Blob to the input through DataTransfer. The CDP
523
+ // channel never carries the bytes. Falls back to Playwright's native
524
+ // setInputFiles if the browser fetch fails (small files, missing URL).
525
+ log('info', `[yt-pw] setInputFiles(video) via in-browser fetch (bypass CDP 50MB cap)…`);
526
+ let injected = false;
527
+ if (video_url) {
528
+ try {
529
+ injected = await page.evaluate(async ({ url, selector }) => {
530
+ const r = await fetch(url, { credentials: 'omit' });
531
+ if (!r.ok) throw new Error(`fetch ${r.status}`);
532
+ const blob = await r.blob();
533
+ if (!blob || !blob.size) throw new Error('empty blob');
534
+ const fname = (url.split('?')[0].split('/').pop()) || 'video.mp4';
535
+ const file = new File([blob], fname, { type: blob.type || 'video/mp4' });
536
+ const inputs = Array.from(document.querySelectorAll(selector));
537
+ const input = inputs.find((el) => /video/i.test(el.accept || '')) || inputs[0];
538
+ if (!input) throw new Error('input not found');
539
+ const dt = new DataTransfer();
540
+ dt.items.add(file);
541
+ input.files = dt.files;
542
+ input.dispatchEvent(new Event('change', { bubbles: true }));
543
+ return true;
544
+ }, { url: video_url, selector: S.fileInput });
545
+ log('info', `[yt-pw] in-browser fetch upload OK`);
546
+ } catch (e) {
547
+ log('warn', `[yt-pw] in-browser fetch upload failed: ${String(e.message || e).slice(0, 160)} — falling back to Playwright setInputFiles`);
548
+ }
549
+ }
550
+ if (!injected) {
551
+ await page.locator(S.fileInput).setInputFiles(videoPath);
552
+ }
520
553
  log('info', `[yt-pw] file set; waiting for the metadata form to appear…`);
521
554
 
522
555
  // 6) Wait for the Title field to be ready (Studio renders it as the file